diff --git a/MsvmPkg/IoMmuDxe/IoMmuBounce.c b/MsvmPkg/IoMmuDxe/IoMmuBounce.c new file mode 100644 index 0000000000..914d975003 --- /dev/null +++ b/MsvmPkg/IoMmuDxe/IoMmuBounce.c @@ -0,0 +1,448 @@ +/** @file + Bounce buffer implementation for the Hyper-V IOMMU driver. + + Provides host-visible bounce buffer management for DMA operations in + isolated Hyper-V virtual machines. Adapted from the NvmExpressBounce + implementation to be generic and usable by any DMA-capable driver. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "IoMmuBounce.h" + +#include +#include + +// +// Module globals for host visibility and shared GPA translation. +// +EFI_HV_IVM_PROTOCOL *mHvIvm; +EFI_PHYSICAL_ADDRESS mSharedGpaBoundary; +UINT64 mCanonicalizationMask; + +// +// Allocation tracking. +// +LIST_ENTRY mAllocContextListHead; + +// +// Pre-allocated bounce block pool. Each block is a contiguous host-visible +// region; Map() sub-allocates contiguous page runs from a block via the +// per-block AllocBitmap. +// +LIST_ENTRY mBounceBlockListHead; + + +/** + Initialize the bounce buffer subsystem. Caches PCDs and locates + the hypervisor IVM protocol. + + @retval EFI_SUCCESS Initialization successful. + @retval other Failed to locate the HV IVM protocol. +**/ +EFI_STATUS +IoMmuInitializeBounce ( + VOID + ) +{ + InitializeListHead (&mAllocContextListHead); + InitializeListHead (&mBounceBlockListHead); + + mSharedGpaBoundary = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdIsolationSharedGpaBoundary); + mCanonicalizationMask = PcdGet64 (PcdIsolationSharedGpaCanonicalizationBitmask); + + if (!IsIsolated ()) { + // + // Bounce buffering and host-visibility hypercalls are not used when the + // VM is not isolated, so don't require the HV IVM protocol. + // + mHvIvm = NULL; + return EFI_SUCCESS; + } + + return gBS->LocateProtocol (&gEfiHvIvmProtocolGuid, NULL, (VOID **)&mHvIvm); +} + + +/** + Return TRUE if bounce buffering should be used for DMA operations. + + @retval TRUE The VM is isolated and bounce buffering is required. + @retval FALSE No isolation; DMA can access all memory directly. +**/ +BOOLEAN +IoMmuIsBounceActive ( + VOID + ) +{ + return IsIsolated (); +} + + +/** + Given an address (VA or PA), strip canonicalization and return the + shared GPA above the shared GPA boundary. + + @param[in] Address Input address. + + @retval The shared physical address. +**/ +EFI_PHYSICAL_ADDRESS +IoMmuGetSharedPa ( + IN VOID *Address + ) +{ + EFI_PHYSICAL_ADDRESS Addr; + + Addr = (EFI_PHYSICAL_ADDRESS)(UINTN)Address; + Addr &= ~mCanonicalizationMask; + if (Addr < mSharedGpaBoundary) { + Addr += mSharedGpaBoundary; + } + + return Addr; +} + + +/** + Given an address (VA or PA), return a canonicalized pointer to the + shared GPA alias. + + @param[in] Address Input address. + + @retval Canonicalized shared VA pointer. +**/ +VOID * +IoMmuGetSharedVa ( + IN VOID *Address + ) +{ + return (VOID *)(UINTN)(IoMmuGetSharedPa (Address) | mCanonicalizationMask); +} + + +/** + Make an address range host-visible for DMA. + + @param[in] BaseAddress Base address of the range. + @param[in] PageCount Number of pages in the range. + @param[out] VisibilityContext Context for revoking visibility later. + + @retval EFI_SUCCESS Range is now host-visible. + @retval other Hypervisor call failed. +**/ +EFI_STATUS +IoMmuMakeAddressRangeShared ( + IN VOID *BaseAddress, + IN UINT32 PageCount, + OUT IOMMU_HOST_VISIBILITY_CONTEXT *VisibilityContext + ) +{ + EFI_STATUS Status; + + if (!IsIsolated ()) { + // + // No isolation: host already has access to all guest memory, so + // there is no visibility hypercall to make. Clear the protection + // handle so a later IoMmuMakeAddressRangePrivate is a no-op too. + // + if (VisibilityContext != NULL) { + VisibilityContext->RangeProtectionHandle = NULL; + } + return EFI_SUCCESS; + } + + Status = mHvIvm->MakeAddressRangeHostVisible ( + mHvIvm, + HV_MAP_GPA_READABLE | HV_MAP_GPA_WRITABLE, + BaseAddress, + PageCount * EFI_PAGE_SIZE, + FALSE, + &VisibilityContext->RangeProtectionHandle + ); + + return Status; +} + + +/** + Revoke host visibility for an address range. + + @param[in] VisibilityContext Context from a prior MakeAddressRangeShared call. +**/ +VOID +IoMmuMakeAddressRangePrivate ( + IN IOMMU_HOST_VISIBILITY_CONTEXT *VisibilityContext + ) +{ + if (!IsIsolated ()) { + // + // No isolation: nothing was made host-visible, so nothing to revoke. + // + return; + } + + mHvIvm->MakeAddressRangeNotHostVisible (mHvIvm, &VisibilityContext->RangeProtectionHandle); +} + + +// +// --------------------------------------------------------------------------- +// Pre-allocated bounce block pool. +// +// Each IOMMU_BOUNCE_BLOCK is a contiguous, host-visible region of pages +// allocated below 4GB. Map() requests are satisfied by sub-allocating a +// contiguous run of free pages from one of the blocks (via the per-block +// AllocBitmap). If no existing block can satisfy a request, a new block is +// allocated and made host-visible (one hypercall per new block, not per +// Map). Blocks are kept around for the lifetime of the driver to amortize +// the cost of host-visibility hypercalls across many DMA operations. +// --------------------------------------------------------------------------- +// + +/** + Find the lowest contiguous run of `RunLength` clear bits in `Bitmap`, + considering only bits [0, BitmapSize). Returns the starting bit index + via *StartBit on success. +**/ +STATIC +BOOLEAN +FindFreeRun ( + IN UINT64 *Bitmap, + IN UINT32 BitmapSize, + IN UINT32 RunLength, + OUT UINT32 *StartBit + ) +{ + UINT32 i; + UINT32 Run; + + if ((RunLength == 0) || (RunLength > BitmapSize)) { + return FALSE; + } + + Run = 0; + for (i = 0; i < BitmapSize; i++) { + if ((Bitmap[i >> 6] & ((UINT64)1 << (i & 63))) == 0) { + Run++; + if (Run == RunLength) { + *StartBit = i + 1 - RunLength; + return TRUE; + } + } else { + Run = 0; + } + } + + return FALSE; +} + + +/** + Set or clear a contiguous run of `Count` bits starting at `Start` in + `Bitmap`. `Set` selects between OR (TRUE) and AND-NOT (FALSE). +**/ +STATIC +VOID +UpdateBitmapRun ( + IN OUT UINT64 *Bitmap, + IN UINT32 Start, + IN UINT32 Count, + IN BOOLEAN Set + ) +{ + UINT32 i; + UINT32 Bit; + UINT64 Mask; + + for (i = 0; i < Count; i++) { + Bit = Start + i; + Mask = (UINT64)1 << (Bit & 63); + if (Set) { + Bitmap[Bit >> 6] |= Mask; + } else { + Bitmap[Bit >> 6] &= ~Mask; + } + } +} + + +/** + Allocate a new bounce block of `PageCount` pages, make it host-visible, + and insert it at the tail of the bounce block list. + + @param[in] PageCount Number of pages in the new block. + @param[out] BlockOut The newly allocated block on success. + + @retval EFI_SUCCESS Block allocated and registered. + @retval EFI_OUT_OF_RESOURCES Allocation or hypercall failed. +**/ +EFI_STATUS +IoMmuPreAllocateBounceBlock ( + IN UINT32 PageCount, + OUT PIOMMU_BOUNCE_BLOCK *BlockOut + ) +{ + EFI_STATUS Status; + PIOMMU_BOUNCE_BLOCK Block; + EFI_PHYSICAL_ADDRESS PhysicalAddress; + UINT32 BitmapWordCount; + + ASSERT (PageCount > 0); + + Block = AllocateZeroPool (sizeof (IOMMU_BOUNCE_BLOCK)); + if (Block == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + BitmapWordCount = (PageCount + 63) / 64; + Block->AllocBitmap = AllocateZeroPool ((UINTN)BitmapWordCount * sizeof (UINT64)); + if (Block->AllocBitmap == NULL) { + FreePool (Block); + return EFI_OUT_OF_RESOURCES; + } + + // + // Allocate the block below 4GB so it can satisfy both 32-bit and + // 64-bit DMA Map() requests without further constraints. + // + PhysicalAddress = SIZE_4GB - 1; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesData, + PageCount, + &PhysicalAddress + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "IoMmu: AllocateBounceBlock: AllocatePages(%d pages, <4GB) failed: %r\n", + PageCount, Status)); + FreePool (Block->AllocBitmap); + FreePool (Block); + return Status; + } + + Block->Signature = IOMMU_BOUNCE_BLOCK_SIGNATURE; + Block->BlockBase = (VOID *)(UINTN)PhysicalAddress; + Block->BlockPageCount = PageCount; + Block->BitmapWordCount = BitmapWordCount; + Block->InUsePageCount = 0; + Block->IsHostVisible = FALSE; + + Status = IoMmuMakeAddressRangeShared ( + Block->BlockBase, + PageCount, + &Block->VisibilityContext + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "IoMmu: AllocateBounceBlock: MakeAddressRangeShared failed: %r\n", + Status)); + gBS->FreePages (PhysicalAddress, PageCount); + FreePool (Block->AllocBitmap); + FreePool (Block); + return Status; + } + + Block->IsHostVisible = TRUE; + InsertTailList (&mBounceBlockListHead, &Block->Link); + + DEBUG ((DEBUG_INFO, + "IoMmu: AllocateBounceBlock: Block=%p Base=%p Pages=%d\n", + Block, Block->BlockBase, PageCount)); + + *BlockOut = Block; + return EFI_SUCCESS; +} + + +EFI_STATUS +IoMmuAcquireBouncePages ( + IN UINT32 PageCount, + OUT PIOMMU_BOUNCE_BLOCK *Block, + OUT UINT32 *StartPageIndex, + OUT VOID **BounceBase + ) +{ + LIST_ENTRY *Entry; + PIOMMU_BOUNCE_BLOCK Candidate; + UINT32 StartBit; + EFI_STATUS Status; + UINT32 NewBlockPages; + + if (PageCount == 0) { + return EFI_INVALID_PARAMETER; + } + + StartBit = 0; + + // + // Try to satisfy from an existing pooled block. + // + for (Entry = GetFirstNode (&mBounceBlockListHead); + !IsNull (&mBounceBlockListHead, Entry); + Entry = GetNextNode (&mBounceBlockListHead, Entry)) + { + Candidate = BASE_CR (Entry, IOMMU_BOUNCE_BLOCK, Link); + + if (PageCount > Candidate->BlockPageCount) { + continue; + } + + if (FindFreeRun (Candidate->AllocBitmap, Candidate->BlockPageCount, PageCount, &StartBit)) { + UpdateBitmapRun (Candidate->AllocBitmap, StartBit, PageCount, TRUE); + Candidate->InUsePageCount += PageCount; + + *Block = Candidate; + *StartPageIndex = StartBit; + *BounceBase = (VOID *)((UINTN)Candidate->BlockBase + ((UINTN)StartBit * EFI_PAGE_SIZE)); + return EFI_SUCCESS; + } + } + + // + // No existing block can fit. Allocate a new pooled block large enough + // for this request (at least the default block size to leave room for + // future sub-allocations). The new block requires one + // MakeAddressRangeHostVisible hypercall; subsequent same-or-smaller + // requests reuse the block with no hypercall. + // + NewBlockPages = PageCount; + if (NewBlockPages < IOMMU_BOUNCE_GROWTH_BLOCK_PAGES) { + NewBlockPages = IOMMU_BOUNCE_GROWTH_BLOCK_PAGES; + } + + Status = IoMmuPreAllocateBounceBlock (NewBlockPages, &Candidate); + if (EFI_ERROR (Status)) { + return Status; + } + DEBUG ((DEBUG_INFO, + "IoMmuAcquireBouncePages: Allocated new bounce block %p with %d pages to satisfy request for %d pages\n", + Candidate, Candidate->BlockPageCount, PageCount)); + UpdateBitmapRun (Candidate->AllocBitmap, 0, PageCount, TRUE); + Candidate->InUsePageCount = PageCount; + + *Block = Candidate; + *StartPageIndex = 0; + *BounceBase = Candidate->BlockBase; + return EFI_SUCCESS; +} + + +VOID +IoMmuReleaseBouncePages ( + IN PIOMMU_BOUNCE_BLOCK Block, + IN UINT32 StartPageIndex, + IN UINT32 PageCount + ) +{ + ASSERT (Block != NULL); + ASSERT (Block->Signature == IOMMU_BOUNCE_BLOCK_SIGNATURE); + ASSERT (PageCount > 0); + ASSERT (StartPageIndex + PageCount <= Block->BlockPageCount); + + UpdateBitmapRun (Block->AllocBitmap, StartPageIndex, PageCount, FALSE); + Block->InUsePageCount -= PageCount; +} diff --git a/MsvmPkg/IoMmuDxe/IoMmuBounce.h b/MsvmPkg/IoMmuDxe/IoMmuBounce.h new file mode 100644 index 0000000000..3ab011285c --- /dev/null +++ b/MsvmPkg/IoMmuDxe/IoMmuBounce.h @@ -0,0 +1,205 @@ +/** @file + Bounce buffer types and declarations for the Hyper-V IOMMU driver. + + This module provides bounce buffering for DMA operations in isolated + Hyper-V virtual machines. Memory that needs to be visible to the host + for DMA must be explicitly shared via the hypervisor. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// +// Context for tracking host visibility of an address range. +// +typedef struct _IOMMU_HOST_VISIBILITY_CONTEXT +{ + EFI_HV_PROTECTION_HANDLE RangeProtectionHandle; +} IOMMU_HOST_VISIBILITY_CONTEXT; + +// +// Page counts for bounce blocks. Each block is allocated as a contiguous, +// host-visible region below 4GB. Map() requests are satisfied by +// sub-allocating contiguous page runs from a block. +// +// IOMMU_BOUNCE_INITIAL_BLOCK_PAGES: size of the single block pre-allocated +// at driver entry. Sized to absorb large boot-time DMA transfers (e.g. +// NVMe namespace reads up to ~2 MB) without a lazy allocation. +// +// IOMMU_BOUNCE_GROWTH_BLOCK_PAGES: minimum size used when the pool is +// exhausted and a new block must be allocated on demand. The new block +// is sized to MAX(request, growth) so small requests don't reserve a +// disproportionately large region. +// +#define IOMMU_BOUNCE_INITIAL_BLOCK_PAGES 1024 +#define IOMMU_BOUNCE_GROWTH_BLOCK_PAGES 32 + +// +// IOMMU_BOUNCE_BLOCK - a contiguous, host-visible region of pages backing +// Map() requests. The block is kept (and stays host-visible) for the +// lifetime of the driver. Per-page in-use state is tracked via a bitmap +// sized to BlockPageCount. +// +#define IOMMU_BOUNCE_BLOCK_SIGNATURE SIGNATURE_32('i','o','m','b') + +typedef struct _IOMMU_BOUNCE_BLOCK +{ + UINT32 Signature; + LIST_ENTRY Link; + VOID *BlockBase; // contiguous host-visible base (private VA) + UINT32 BlockPageCount; + UINT32 BitmapWordCount; // number of UINT64 words in AllocBitmap + UINT64 *AllocBitmap; // 1 bit per page; 1 = in use + UINT32 InUsePageCount; + BOOLEAN IsHostVisible; + IOMMU_HOST_VISIBILITY_CONTEXT VisibilityContext; +} IOMMU_BOUNCE_BLOCK, *PIOMMU_BOUNCE_BLOCK; + +// +// MAP_CONTEXT - tracking structure for an active Map operation. Stored as +// the Mapping handle returned to callers. Records which bounce block and +// starting page index were sub-allocated so Unmap can release them. +// +#define IOMMU_MAP_CONTEXT_SIGNATURE SIGNATURE_32('i','o','m','c') + +typedef struct _IOMMU_MAP_CONTEXT +{ + UINT32 Signature; + EDKII_IOMMU_OPERATION Operation; + VOID *HostAddress; + UINTN NumberOfBytes; + VOID *BounceBase; // private VA of the sub-allocated bounce region + UINT32 BouncePageCount; + PIOMMU_BOUNCE_BLOCK BounceBlock; // owning block + UINT32 BounceStartPage; // starting page index within block +} IOMMU_MAP_CONTEXT, *PIOMMU_MAP_CONTEXT; + +// +// ALLOC_CONTEXT - tracking structure for an active AllocateBuffer allocation. +// Used by FreeBuffer to revoke host visibility. +// +typedef struct _IOMMU_ALLOC_CONTEXT +{ + LIST_ENTRY Link; + VOID *OriginalAddress; + UINTN Pages; + IOMMU_HOST_VISIBILITY_CONTEXT VisibilityContext; +} IOMMU_ALLOC_CONTEXT, *PIOMMU_ALLOC_CONTEXT; + + +// +// Bounce buffer initialization. +// +EFI_STATUS +IoMmuInitializeBounce ( + VOID + ); + +// +// Returns TRUE if bounce buffering is active (isolated VM with IOMMU). +// +BOOLEAN +IoMmuIsBounceActive ( + VOID + ); + +// +// Address translation helpers for shared GPA. +// +EFI_PHYSICAL_ADDRESS +IoMmuGetSharedPa ( + IN VOID *Address + ); + +VOID * +IoMmuGetSharedVa ( + IN VOID *Address + ); + +// +// Host visibility management. +// +EFI_STATUS +IoMmuMakeAddressRangeShared ( + IN VOID *BaseAddress, + IN UINT32 PageCount, + OUT IOMMU_HOST_VISIBILITY_CONTEXT *VisibilityContext + ); + +VOID +IoMmuMakeAddressRangePrivate ( + IN IOMMU_HOST_VISIBILITY_CONTEXT *VisibilityContext + ); + +// +// Bounce block pool - pre-allocated, host-visible contiguous regions used +// to satisfy Map() requests without per-Map hypercalls. +// + +/** + Pre-allocate a bounce block of `PageCount` pages, make it host-visible, + and add it to the pool. Used to populate the pool at driver init so the + common-case Map() path needs no hypercall. + + @param[in] PageCount Number of pages in the new block. + @param[out] BlockOut The newly allocated block on success. + + @retval EFI_SUCCESS Block allocated and registered. + @retval EFI_OUT_OF_RESOURCES Allocation or hypercall failed. +**/ +EFI_STATUS +IoMmuPreAllocateBounceBlock ( + IN UINT32 PageCount, + OUT PIOMMU_BOUNCE_BLOCK *BlockOut + ); + +/** + Acquire a contiguous run of bounce pages from the pool. Allocates a new + bounce block (and makes it host-visible) on demand if no existing block + has a sufficient contiguous free run. + + @param[in] PageCount Number of contiguous pages required. + @param[out] Block Owning bounce block. + @param[out] StartPageIndex Starting page index within the block. + @param[out] BounceBase Private VA of the start of the run. + + @retval EFI_SUCCESS Pages acquired. + @retval EFI_OUT_OF_RESOURCES Could not acquire/allocate pages. +**/ +EFI_STATUS +IoMmuAcquireBouncePages ( + IN UINT32 PageCount, + OUT PIOMMU_BOUNCE_BLOCK *Block, + OUT UINT32 *StartPageIndex, + OUT VOID **BounceBase + ); + +/** + Release a previously acquired contiguous run of bounce pages back to the + pool. The pages remain host-visible (the owning block stays host-visible + for its lifetime). + + @param[in] Block Owning bounce block. + @param[in] StartPageIndex Starting page index within the block. + @param[in] PageCount Number of pages to release. +**/ +VOID +IoMmuReleaseBouncePages ( + IN PIOMMU_BOUNCE_BLOCK Block, + IN UINT32 StartPageIndex, + IN UINT32 PageCount + ); diff --git a/MsvmPkg/IoMmuDxe/IoMmuDxe.c b/MsvmPkg/IoMmuDxe/IoMmuDxe.c new file mode 100644 index 0000000000..e5486f857c --- /dev/null +++ b/MsvmPkg/IoMmuDxe/IoMmuDxe.c @@ -0,0 +1,654 @@ +/** @file + Hyper-V IOMMU DXE driver. + + Implements the EDKII_IOMMU_PROTOCOL for Hyper-V isolated virtual machines. + Provides bounce buffering so that DMA operations use host-visible memory. + This driver only installs the protocol when running in an isolated VM; + non-isolated VMs do not need IOMMU-based DMA translation. + + This is a generic implementation: any driver that uses PciIo or IoMmuLib + for DMA (e.g., NvmExpressDxe, StorvscDxe) benefits from this bounce + buffering transparently. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "IoMmuBounce.h" + +#include +#include +#include +#include + +#include + +// +// External globals from IoMmuBounce.c +// +extern LIST_ENTRY mAllocContextListHead; + + +/** + EDKII_IOMMU_PROTOCOL.SetAttribute - Set IOMMU access attributes. + + For Hyper-V isolation, this is a no-op since visibility is managed + explicitly through the bounce buffer mechanism rather than hardware + page tables. + + @param[in] This Protocol instance. + @param[in] DeviceHandle Device requesting access. + @param[in] Mapping Mapping handle from Map(). + @param[in] IoMmuAccess Access flags (READ/WRITE). + + @retval EFI_SUCCESS Always succeeds. +**/ +STATIC +EFI_STATUS +EFIAPI +IoMmuSetAttribute ( + IN EDKII_IOMMU_PROTOCOL *This, + IN EFI_HANDLE DeviceHandle, + IN VOID *Mapping, + IN UINT64 IoMmuAccess + ) +{ + return EFI_SUCCESS; +} + + +/** + EDKII_IOMMU_PROTOCOL.Map - Map a host address for DMA. + + For BusMasterCommonBuffer: the memory was already made host-visible by + AllocateBuffer; returns the shared physical address directly. + + For BusMasterRead (host→device): acquires bounce pages, copies data into + them, and returns the bounce physical address. + + For BusMasterWrite (device→host): acquires bounce pages, zeroes them, + and returns the bounce physical address. Data is copied back on Unmap. + + @param[in] This Protocol instance. + @param[in] Operation DMA operation type. + @param[in] HostAddress System memory address to map. + @param[in,out] NumberOfBytes Bytes to map / bytes mapped. + @param[out] DeviceAddress Resulting DMA address for the device. + @param[out] Mapping Opaque handle for Unmap(). + + @retval EFI_SUCCESS Mapping created successfully. + @retval EFI_OUT_OF_RESOURCES Could not allocate bounce pages. +**/ +STATIC +EFI_STATUS +EFIAPI +IoMmuMap ( + IN EDKII_IOMMU_PROTOCOL *This, + IN EDKII_IOMMU_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +{ + if (!IoMmuIsBounceActive ()) { + // + // Non-isolated path. Mirrors RootBridgeIoMap()'s behavior when + // IoMmuIsPresent() == FALSE: a non-64-bit Read/Write whose buffer + // crosses the 4GB boundary is bounced into memory below 4GB so + // 32-bit-only bus masters can address it. Everything else is an + // identity mapping. CommonBuffer cannot be remapped here; the + // memory has to already be addressable, which IoMmuAllocateBuffer + // guarantees by allocating below 4GB whenever DUAL_ADDRESS_CYCLE + // is not requested. + // + EFI_PHYSICAL_ADDRESS PhysicalAddress; + + PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress; + + if ((Operation != EdkiiIoMmuOperationBusMasterCommonBuffer) && + (Operation != EdkiiIoMmuOperationBusMasterCommonBuffer64) && + (Operation != EdkiiIoMmuOperationBusMasterRead64) && + (Operation != EdkiiIoMmuOperationBusMasterWrite64) && + ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) { + + PIOMMU_MAP_CONTEXT MapContext; + EFI_PHYSICAL_ADDRESS MappedAddress; + UINTN Pages; + EFI_STATUS Status; + + Pages = EFI_SIZE_TO_PAGES (*NumberOfBytes); + MappedAddress = SIZE_4GB - 1; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesData, + Pages, + &MappedAddress + ); + if (EFI_ERROR (Status)) { + *NumberOfBytes = 0; + return Status; + } + + // + // Read = host->device: pre-populate the bounce buffer. + // + if ((Operation == EdkiiIoMmuOperationBusMasterRead) || + (Operation == EdkiiIoMmuOperationBusMasterRead64)) { + CopyMem ( + (VOID *)(UINTN)MappedAddress, + HostAddress, + *NumberOfBytes + ); + } + + MapContext = AllocatePool (sizeof (IOMMU_MAP_CONTEXT)); + if (MapContext == NULL) { + gBS->FreePages (MappedAddress, Pages); + *NumberOfBytes = 0; + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (MapContext, sizeof (*MapContext)); + MapContext->Signature = IOMMU_MAP_CONTEXT_SIGNATURE; + MapContext->Operation = Operation; + MapContext->HostAddress = HostAddress; + MapContext->NumberOfBytes = *NumberOfBytes; + MapContext->BounceBase = (VOID *)(UINTN)MappedAddress; + MapContext->BouncePageCount = (UINT32)Pages; + // + // BounceBlock == NULL discriminates this non-isolated <4GB + // bounce path from the isolated bounce-block sub-allocation + // path in IoMmuUnmap. + // + MapContext->BounceBlock = NULL; + MapContext->BounceStartPage = 0; + + *DeviceAddress = MappedAddress; + *Mapping = MapContext; + return EFI_SUCCESS; + } + + // + // Either the device can DMA above 4GB or the buffer already lives + // below 4GB; identity-map. + // + *DeviceAddress = PhysicalAddress; + *Mapping = NULL; + return EFI_SUCCESS; + } + + // + // For BusMasterCommonBuffer, the memory was already made host-visible + // via AllocateBuffer. Just return the shared PA. + // + if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer || + Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) { + *DeviceAddress = IoMmuGetSharedPa (HostAddress); + *Mapping = NULL; + return EFI_SUCCESS; + } + + // + // For BusMasterRead/Write, sub-allocate a contiguous run of pages from + // the pre-allocated bounce block pool. The owning block has already + // been made host-visible at allocation time, so this avoids the + // per-Map MakeAddressRangeHostVisible hypercall. + // + { + PIOMMU_MAP_CONTEXT MapContext; + UINT32 BouncePageCount; + VOID *BounceBase; + VOID *SharedVa; + EFI_STATUS Status; + PIOMMU_BOUNCE_BLOCK BounceBlock; + UINT32 BounceStartPage; + UINTN RequestedPages; + + RequestedPages = EFI_SIZE_TO_PAGES (*NumberOfBytes); + + // + // Bounce-block bookkeeping (page indices, bitmap offsets, + // BlockPageCount) is UINT32 throughout. Reject any request that + // would not fit in 32 bits (>16 TiB) up front rather than silently + // truncating. EDKII_IOMMU_PROTOCOL.Map has no realistic caller at + // this size, but the explicit check makes the contract clear. + // + if (RequestedPages > MAX_UINT32) { + DEBUG ((DEBUG_ERROR, + "IoMmuMap: Request too large: %lu pages (max %u)\n", + (UINT64)RequestedPages, MAX_UINT32)); + return EFI_OUT_OF_RESOURCES; + } + + BouncePageCount = (UINT32)RequestedPages; + + // + // The bounce block pool always allocates blocks below 4GB, so the + // run returned here is safe for both 32-bit and 64-bit DMA devices. + // Operation-based DmaMemoryTop checks (4GB cap) are therefore + // implicitly satisfied. + // + Status = IoMmuAcquireBouncePages ( + BouncePageCount, + &BounceBlock, + &BounceStartPage, + &BounceBase + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "IoMmuMap: Failed to acquire %d bounce pages: %r\n", + BouncePageCount, Status)); + return EFI_OUT_OF_RESOURCES; + } + + SharedVa = IoMmuGetSharedVa (BounceBase); + + // + // Zero the entire bounce buffer. For BusMasterRead (host->device), + // this prevents leaking guest data in unused page fragments. For + // BusMasterWrite (device->host), this provides a clean buffer that + // the device will write into (data copied back on Unmap). + // + ZeroMem (SharedVa, (UINTN)BouncePageCount * EFI_PAGE_SIZE); + + if (Operation == EdkiiIoMmuOperationBusMasterRead || + Operation == EdkiiIoMmuOperationBusMasterRead64) { + // + // Host->device transfer: copy data into the zeroed bounce buffer. + // + CopyMem (SharedVa, HostAddress, *NumberOfBytes); + } + + // + // Return the host-visible physical address. + // + *DeviceAddress = IoMmuGetSharedPa (BounceBase); + + // + // Allocate mapping context for Unmap. + // + MapContext = AllocateZeroPool (sizeof (IOMMU_MAP_CONTEXT)); + if (MapContext == NULL) { + IoMmuReleaseBouncePages (BounceBlock, BounceStartPage, BouncePageCount); + return EFI_OUT_OF_RESOURCES; + } + + MapContext->Signature = IOMMU_MAP_CONTEXT_SIGNATURE; + MapContext->Operation = Operation; + MapContext->HostAddress = HostAddress; + MapContext->NumberOfBytes = *NumberOfBytes; + MapContext->BounceBase = BounceBase; + MapContext->BouncePageCount = BouncePageCount; + MapContext->BounceBlock = BounceBlock; + MapContext->BounceStartPage = BounceStartPage; + + *Mapping = MapContext; + } + + return EFI_SUCCESS; +} + + +/** + EDKII_IOMMU_PROTOCOL.Unmap - Complete a Map operation and release resources. + + For BusMasterWrite operations, copies data from the bounce buffer back + to the original host address before releasing the bounce pages. + + @param[in] This Protocol instance. + @param[in] Mapping Mapping handle from Map(). + + @retval EFI_SUCCESS Unmap completed. +**/ +STATIC +EFI_STATUS +EFIAPI +IoMmuUnmap ( + IN EDKII_IOMMU_PROTOCOL *This, + IN VOID *Mapping + ) +{ + PIOMMU_MAP_CONTEXT MapContext; + + if (Mapping == NULL) { + // + // NULL mapping: BusMasterCommonBuffer or no-op. Nothing to do. + // + return EFI_SUCCESS; + } + + MapContext = (PIOMMU_MAP_CONTEXT)Mapping; + ASSERT (MapContext->Signature == IOMMU_MAP_CONTEXT_SIGNATURE); + + // + // Non-isolated <4GB bounce path. Mirrors RootBridgeIoUnmap()'s + // no-IOMMU path: for Write (device->host) copy the bounce buffer + // back into the original host buffer, then free the bounce pages + // and the context. + // + if (MapContext->BounceBlock == NULL) { + if ((MapContext->Operation == EdkiiIoMmuOperationBusMasterWrite) || + (MapContext->Operation == EdkiiIoMmuOperationBusMasterWrite64)) { + CopyMem ( + MapContext->HostAddress, + MapContext->BounceBase, + MapContext->NumberOfBytes + ); + } + + gBS->FreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)MapContext->BounceBase, + MapContext->BouncePageCount + ); + FreePool (MapContext); + return EFI_SUCCESS; + } + + // + // Isolated bounce-block path. + // + // For BusMasterWrite (device->host), copy data from bounce to host. + // + if (MapContext->Operation == EdkiiIoMmuOperationBusMasterWrite || + MapContext->Operation == EdkiiIoMmuOperationBusMasterWrite64) { + VOID *SharedVa; + + SharedVa = IoMmuGetSharedVa (MapContext->BounceBase); + CopyMem ( + MapContext->HostAddress, + SharedVa, + MapContext->NumberOfBytes + ); + } + + // + // Release the bounce pages back to the pool. The owning bounce block + // remains host-visible for its lifetime, so no per-Unmap hypercall is + // required. + // + if ((MapContext->Operation != EdkiiIoMmuOperationBusMasterCommonBuffer) && + (MapContext->Operation != EdkiiIoMmuOperationBusMasterCommonBuffer64)) + { + IoMmuReleaseBouncePages ( + MapContext->BounceBlock, + MapContext->BounceStartPage, + MapContext->BouncePageCount + ); + FreePool (MapContext); + + } + + return EFI_SUCCESS; +} + + +/** + EDKII_IOMMU_PROTOCOL.AllocateBuffer - Allocate DMA-capable memory. + + Allocates pages and makes them host-visible so the device can DMA to them. + Returns a canonicalized shared VA that maps above the shared GPA boundary. + + When EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE is not set the allocation is + constrained below 4GB and Type is forced to AllocateMaxAddress. When the + attribute is set, the caller-supplied Type is used as-is. + + @param[in] This Protocol instance. + @param[in] Type Allocation type; overridden to AllocateMaxAddress + when dual-address-cycle is not set. + @param[in] MemoryType Memory type (EfiBootServicesData or EfiRuntimeServicesData). + @param[in] Pages Number of pages to allocate. + @param[in,out] HostAddress On output, the shared VA pointer. + @param[in] Attributes Allocation attributes (EDKII_IOMMU_ATTRIBUTE_*). + + @retval EFI_SUCCESS Memory allocated and made host-visible. + @retval EFI_INVALID_PARAMETER This, HostAddress, or Pages is invalid. + @retval EFI_OUT_OF_RESOURCES Allocation or visibility call failed. +**/ +STATIC +EFI_STATUS +EFIAPI +IoMmuAllocateBuffer ( + IN EDKII_IOMMU_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT VOID **HostAddress, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + IOMMU_HOST_VISIBILITY_CONTEXT VisibilityContext; + PIOMMU_ALLOC_CONTEXT AllocContext; + EFI_PHYSICAL_ADDRESS PhysicalAddress; + + if ((This == NULL) || (Pages == 0) || (HostAddress == NULL)) { + DEBUG ((DEBUG_ERROR, "IoMmuAllocateBuffer: Invalid parameter\n")); + Status = EFI_INVALID_PARAMETER; + goto End; + } + + PhysicalAddress = MAX_UINTN; + + if ((Attributes & EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) { + // + // Device cannot address above 4GB; constrain allocation below 4GB. + // + PhysicalAddress = SIZE_4GB - 1; + Type = AllocateMaxAddress; + } + + Status = gBS->AllocatePages ( + Type, + MemoryType, + Pages, + &PhysicalAddress + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "IoMmuAllocateBuffer: Failed to allocate pages: %r\n", Status)); + goto End; + } + + if (!IoMmuIsBounceActive ()) { + // + // Non-isolated: just return the allocated buffer directly. + // + *HostAddress = (VOID *)(UINTN)PhysicalAddress; + goto End; + } + + // + // Make the allocated range host-visible for DMA. + // + Status = IoMmuMakeAddressRangeShared ( + (VOID *)(UINTN)PhysicalAddress, + (UINT32)Pages, + &VisibilityContext + ); + if (EFI_ERROR (Status)) { + gBS->FreePages (PhysicalAddress, Pages); + goto End; + } + + // + // Track this allocation so FreeBuffer can revoke visibility. + // + AllocContext = AllocateZeroPool (sizeof (IOMMU_ALLOC_CONTEXT)); + if (AllocContext == NULL) { + IoMmuMakeAddressRangePrivate (&VisibilityContext); + gBS->FreePages (PhysicalAddress, Pages); + Status = EFI_OUT_OF_RESOURCES; + goto End; + } + + AllocContext->OriginalAddress = (VOID *)(UINTN)PhysicalAddress; + AllocContext->Pages = Pages; + AllocContext->VisibilityContext = VisibilityContext; + InsertTailList (&mAllocContextListHead, &AllocContext->Link); + + // + // Return the canonicalized shared VA. + // + *HostAddress = IoMmuGetSharedVa ((VOID *)(UINTN)PhysicalAddress); + +End: + ASSERT_EFI_ERROR (Status); + return Status; +} + + +/** + EDKII_IOMMU_PROTOCOL.FreeBuffer - Free DMA-capable memory. + + Revokes host visibility for the allocation and frees the pages. + + @param[in] This Protocol instance. + @param[in] Pages Number of pages to free. + @param[in] HostAddress The shared VA returned by AllocateBuffer. + + @retval EFI_SUCCESS Visibility revoked and pages freed. +**/ +STATIC +EFI_STATUS +EFIAPI +IoMmuFreeBuffer ( + IN EDKII_IOMMU_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress + ) +{ + LIST_ENTRY *Entry; + PIOMMU_ALLOC_CONTEXT AllocContext; + + if (!IoMmuIsBounceActive ()) { + return gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, Pages); + } + + // + // Find the tracking entry and revoke host visibility. + // + for (Entry = GetFirstNode (&mAllocContextListHead); + !IsNull (&mAllocContextListHead, Entry); + Entry = GetNextNode (&mAllocContextListHead, Entry)) { + + AllocContext = BASE_CR (Entry, IOMMU_ALLOC_CONTEXT, Link); + + if (IoMmuGetSharedVa (AllocContext->OriginalAddress) == HostAddress) { + RemoveEntryList (Entry); + IoMmuMakeAddressRangePrivate (&AllocContext->VisibilityContext); + FreePool (AllocContext); + break; + } + } + + gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, Pages); + + return EFI_SUCCESS; +} + + +// +// Protocol instance. +// +STATIC EDKII_IOMMU_PROTOCOL mIoMmuProtocol = { + EDKII_IOMMU_PROTOCOL_REVISION, + IoMmuSetAttribute, + IoMmuMap, + IoMmuUnmap, + IoMmuAllocateBuffer, + IoMmuFreeBuffer +}; + + +/** + IoMmuDxe driver entry point. + + Initializes the bounce buffer subsystem and installs the EDKII_IOMMU_PROTOCOL. + In isolated VMs, the protocol provides bounce buffering for DMA. In non-isolated + VMs, the protocol provides simple pass-through behavior (identity mapping, + standard allocation). The protocol is always installed to satisfy the + IoMmuLib AARCH64 DEPEX requirement. + + @param[in] ImageHandle Handle for this driver image. + @param[in] SystemTable Pointer to the UEFI system table. + + @retval EFI_SUCCESS Protocol installed successfully. + @retval other Initialization failed. +**/ +EFI_STATUS +EFIAPI +IoMmuDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + if (IoMmuIsBounceActive ()) { + // + // Bounce buffering is required: initialize the bounce buffer + // subsystem (caches PCDs, locates the HV IVM protocol, initializes + // list heads). + // + Status = IoMmuInitializeBounce (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "IoMmuDxe: Failed to initialize bounce buffers: %r\n", Status)); + return Status; + } + + // + // Pre-allocate one bounce block up front so the common-case Map() + // path needs no AllocatePages/MakeAddressRangeHostVisible hypercall. + // Failure here is non-fatal: subsequent Map() calls will lazily + // allocate a block on demand. + // + { + PIOMMU_BOUNCE_BLOCK InitialBlock; + EFI_STATUS BlockStatus; + + BlockStatus = IoMmuPreAllocateBounceBlock ( + IOMMU_BOUNCE_INITIAL_BLOCK_PAGES, + &InitialBlock + ); + if (EFI_ERROR (BlockStatus)) { + DEBUG ((DEBUG_WARN, + "IoMmuDxe: Failed to pre-allocate initial bounce block: %r\n", + BlockStatus)); + } else { + DEBUG ((DEBUG_INFO, + "IoMmuDxe: Pre-allocated initial bounce block (%d pages)\n", + IOMMU_BOUNCE_INITIAL_BLOCK_PAGES)); + } + } + + DEBUG ((DEBUG_INFO, "IoMmuDxe: Bounce buffers initialized\n")); + } else { + // + // Bounce buffering not required: initialize allocation tracking + // list head only. No bounce blocks or HV protocol needed. + // + InitializeListHead (&mAllocContextListHead); + DEBUG ((DEBUG_INFO, "IoMmuDxe: Bounce buffering inactive, installing pass-through IOMMU protocol\n")); + } + + // + // Always install the IOMMU protocol. On AARCH64, the IoMmuLib has a DEPEX + // on this protocol, so it must be available for VpcivscDxe (and any other + // IoMmuLib consumer) to load. + // + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gEdkiiIoMmuProtocolGuid, + EFI_NATIVE_INTERFACE, + &mIoMmuProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "IoMmuDxe: Failed to install IOMMU protocol: %r\n", Status)); + return Status; + } + + DEBUG ((DEBUG_INFO, "IoMmuDxe: IOMMU protocol installed\n")); + + return EFI_SUCCESS; +} diff --git a/MsvmPkg/IoMmuDxe/IoMmuDxe.inf b/MsvmPkg/IoMmuDxe/IoMmuDxe.inf new file mode 100644 index 0000000000..5bb3a9de73 --- /dev/null +++ b/MsvmPkg/IoMmuDxe/IoMmuDxe.inf @@ -0,0 +1,49 @@ +## @file +# Hyper-V IOMMU DXE Driver +# +# Implements the EDKII_IOMMU_PROTOCOL for Hyper-V isolated virtual machines. +# Provides generic bounce buffering for DMA operations so that any driver +# using PciIo/IoMmuLib can transparently perform DMA in isolated VMs. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = IoMmuDxe + FILE_GUID = 7E3B4F5A-1C2D-4E8F-9A0B-D6C5E4F3A2B1 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = IoMmuDxeEntryPoint + +[Sources] + IoMmuBounce.c + IoMmuDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + MsvmPkg/MsvmPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + IsolationLib + MemoryAllocationLib + PcdLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gEdkiiIoMmuProtocolGuid ## PRODUCES + gEfiHvIvmProtocolGuid ## CONSUMES + +[Pcd] + gMsvmPkgTokenSpaceGuid.PcdIsolationSharedGpaBoundary + gMsvmPkgTokenSpaceGuid.PcdIsolationSharedGpaCanonicalizationBitmask + +[Depex] + TRUE diff --git a/MsvmPkg/MsvmPkg.dec b/MsvmPkg/MsvmPkg.dec index c432df5ee1..b326956e97 100644 --- a/MsvmPkg/MsvmPkg.dec +++ b/MsvmPkg/MsvmPkg.dec @@ -298,7 +298,6 @@ gMsvmPkgTokenSpaceGuid.PcdHostEmulatorsWhenHardwareIsolated|FALSE|BOOLEAN|0x6064 gMsvmPkgTokenSpaceGuid.PcdTpmLocalityRegsEnabled|FALSE|BOOLEAN|0x6065 gMsvmPkgTokenSpaceGuid.PcdMtrrsInitializedAtLoad|FALSE|BOOLEAN|0x6067 - gMsvmPkgTokenSpaceGuid.PcdNvmeNamespaceFilter|FALSE|BOOLEAN|0x6068 # UEFI_CONFIG_PROCESSOR_INFORMATION gMsvmPkgTokenSpaceGuid.PcdProcessorCount|0x0|UINT32|0x6032 diff --git a/MsvmPkg/MsvmPkgAARCH64.dsc b/MsvmPkg/MsvmPkgAARCH64.dsc index a4ee8da466..48dccb27c1 100644 --- a/MsvmPkg/MsvmPkgAARCH64.dsc +++ b/MsvmPkg/MsvmPkgAARCH64.dsc @@ -1,189 +1,190 @@ -## @file -# EFI/Framework Microsoft Virtual Machine Firmware (MSVM) platform -# -# Copyright (c) Microsoft. -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -################################################################################ -# -# Defines Section - statements that will be processed to create a Makefile. -# -################################################################################ -[Defines] - PLATFORM_NAME = Msvm - PLATFORM_GUID = 60d3fbae-b4ed-4a10-9145-f8185dd8b1bd - PLATFORM_VERSION = 0.1 - DSC_SPECIFICATION = 0x00010005 - OUTPUT_DIRECTORY = Build/MsvmAARCH64 - SUPPORTED_ARCHITECTURES = AARCH64 - BUILD_TARGETS = DEBUG|RELEASE - SKUID_IDENTIFIER = DEFAULT - FLASH_DEFINITION = MsvmPkg/MsvmPkgAARCH64.fdf - -# -# Defines for the pre-built BaseCryptLib -# - PEI_CRYPTO_SERVICES = TINY_SHA - DXE_CRYPTO_SERVICES = ALL - PEI_CRYPTO_ARCH = AARCH64 - DXE_CRYPTO_ARCH = AARCH64 - -################################################################################ -# +## @file +# EFI/Framework Microsoft Virtual Machine Firmware (MSVM) platform +# +# Copyright (c) Microsoft. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + PLATFORM_NAME = Msvm + PLATFORM_GUID = 60d3fbae-b4ed-4a10-9145-f8185dd8b1bd + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/MsvmAARCH64 + SUPPORTED_ARCHITECTURES = AARCH64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + FLASH_DEFINITION = MsvmPkg/MsvmPkgAARCH64.fdf + +# +# Defines for the pre-built BaseCryptLib +# + PEI_CRYPTO_SERVICES = TINY_SHA + DXE_CRYPTO_SERVICES = ALL + PEI_CRYPTO_ARCH = AARCH64 + DXE_CRYPTO_ARCH = AARCH64 + +################################################################################ +# # BuildOptions Section - extra build flags -# TODO: There should be only one [BuildOptions]. -# -################################################################################ -[BuildOptions] +# TODO: There should be only one [BuildOptions]. +# +################################################################################ +[BuildOptions] *_*_*_GENFW_FLAGS = --keepexceptiontable *_*_*_CC_FLAGS = -D MS_HYP_CHANGE_BEGIN -D MS_HYP_CHANGE -D MS_HYP -D MU_CHANGE - DEBUG_*_*_CC_FLAGS = -D DEBUG_PLATFORM + DEBUG_*_*_CC_FLAGS = -D DEBUG_PLATFORM *_GCC_*_ASLDLINK_FLAGS = -z common-page-size=0x1000 *_GCC_*_DLINK_FLAGS = -z common-page-size=0x1000 - - # Workaround https://github.com/tianocore/edk2/pull/11535/changes/38760819a84de03127e0d93abd238eee2ce7a6e8 - # BaseTools/Conf: Make ASLCC_FLAGS independent of CC_FLAGS - # GenFW:ConvertELF fails otherwise. - # Ideal, but does not work: *_GCC_AARCH64_ASLCC_FLAGS = $(GCC_AARCH64_CC_FLAGS) - *_GCC_AARCH64_ASLCC_FLAGS = -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -ffunction-sections -fdata-sections -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -ffixed-x18 -mstack-protector-guard=global - -# ARM64 has a UEFI spec requirement that RuntimeServiceCode/Data is 64K aligned + + # Workaround https://github.com/tianocore/edk2/pull/11535/changes/38760819a84de03127e0d93abd238eee2ce7a6e8 + # BaseTools/Conf: Make ASLCC_FLAGS independent of CC_FLAGS + # GenFW:ConvertELF fails otherwise. + # Ideal, but does not work: *_GCC_AARCH64_ASLCC_FLAGS = $(GCC_AARCH64_CC_FLAGS) + *_GCC_AARCH64_ASLCC_FLAGS = -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -ffunction-sections -fdata-sections -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -ffixed-x18 -mstack-protector-guard=global + +# ARM64 has a UEFI spec requirement that RuntimeServiceCode/Data is 64K aligned # This applies to in-memory section alignment, and need not apply to file system alignment. -[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] MSFT:*_*_AARCH64_DLINK_FLAGS = -align:0x10000 *_CLANGPDB_AARCH64_DLINK_FLAGS = -align:0x10000 *_GCC_AARCH64_ASLDLINK_FLAGS = -z common-page-size=0x10000 *_GCC_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000 - -[BuildOptions.common.EDKII.SEC, BuildOptions.common.EDKII.PEIM, BuildOptions.common.EDKII.PEI_CORE] + +[BuildOptions.common.EDKII.SEC, BuildOptions.common.EDKII.PEIM, BuildOptions.common.EDKII.PEI_CORE] MSFT:*_*_*_DLINK_FLAGS = -align:4096 -filealign:4096 *_CLANGPDB_*_DLINK_FLAGS = -align:4096 -filealign:4096 - -################################################################################ -# -# SKU Identification section - list of all SKU IDs supported by this Platform. -# -################################################################################ -[SkuIds] - 0|DEFAULT - -################################################################################ -# -# Library Class section -# -# Library class names used by this platform and the implementations of those -# libraries. | -# -################################################################################ - -# -# Library instances to use by default for all modules and phases unless overridden below -# -[LibraryClasses] - AdvancedLoggerAccessLib|AdvLoggerPkg/Library/AdvancedLoggerAccessLib/AdvancedLoggerAccessLib.inf - AdvancedLoggerHdwPortLib|AdvLoggerPkg/Library/AdvancedLoggerHdwPortLib/AdvancedLoggerHdwPortLib.inf - ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf - ArmMmuLib|UefiCpuPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf - ArmMonitorLib|ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf - ArmSmcLib|MdePkg/Library/ArmSmcLib/ArmSmcLib.inf - ArmTrngLib|MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf - AssertLib|AdvLoggerPkg/Library/AssertLib/AssertLib.inf - BaseLib|MdePkg/Library/BaseLib/BaseLib.inf - BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf - BiosDeviceLib|MsvmPkg/Library/BiosDeviceLib/BiosDeviceLib.inf - CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf - CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf - CrashLib|MsvmPkg/Library/CrashLib/CrashLib.inf - CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf - CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf - DebugLib|AdvLoggerPkg/Library/BaseDebugLibAdvancedLogger/BaseDebugLibAdvancedLogger.inf - DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf - DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - DefaultExceptionHandlerLib|MsvmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf - DeviceStateLib|MdeModulePkg/Library/DeviceStateLib/DeviceStateLib.inf - DisplayDeviceStateLib|MsGraphicsPkg/Library/ColorBarDisplayDeviceStateLib/ColorBarDisplayDeviceStateLib.inf - EmclLib|MsvmPkg/Library/EmclLib/EmclLib.inf - FltUsedLib|MsCorePkg/Library/FltUsedLib/FltUsedLib.inf - FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf - HwResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf - ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf - IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf - IsolationLib|MsvmPkg/Library/IsolationLib/IsolationLib.inf - MathLib|MsCorePkg/Library/MathLib/MathLib.inf - MmuLib|ArmPkg/Library/MmuLib/BaseMmuLib.inf - MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf - MsBaseLib|MsvmPkg/Library/MsBaseLib/MsBaseLib.inf - MsBootPolicyLib|MsvmPkg/Library/MsBootPolicyLib/MsBootPolicyLib.inf - OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf - PanicLib|MdePkg/Library/BasePanicLibNull/BasePanicLibNull.inf - PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf - PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf - PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf - PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf - RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf - ResetUtilityLib|MdeModulePkg/Library/ResetUtilityLib/ResetUtilityLib.inf - SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf - StackCheckFailureHookLib|MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf - StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf - SecurityLockAuditLib|MdeModulePkg/Library/SecurityLockAuditDebugMessageLib/SecurityLockAuditDebugMessageLib.inf ##MSCHANGE - SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf - SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf - Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf - Tpm2HelpLib|SecurityPkg/Library/Tpm2HelpLib/Tpm2HelpLib.inf - TimerLib|MsvmPkg/Library/HvTimerLib/HvTimerLib.inf - UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf - UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf - UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf - UiRectangleLib|MsGraphicsPkg/Library/BaseUiRectangleLib/BaseUiRectangleLib.inf - VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf - -!if $(DEBUGLIB_SERIAL) == 1 - SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf - PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf -!endif - - ## MS_CHANGE_? - # MeasuredBoot and Other TPM-Based Security - Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf - Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf - TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf - Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf - Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf - OemTpm2InitLib|SecurityPkg/Library/OemTpm2InitLibNull/OemTpm2InitLib.inf ## MS_CHANGE_? - Tcg2PreUefiEventLogLib|SecurityPkg/Library/Tcg2PreUefiEventLogLibNull/Tcg2PreUefiEventLogLibNull.inf - ## MS_CHANGE_? - - # MsCore BDS & FrontPage Libs - PlatformBootManagerLib|MsCorePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf - DeviceBootManagerLib|MsvmPkg/Library/DeviceBootManagerLib/DeviceBootManagerLib.inf - UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf - MsLogoLib|MsvmPkg/Library/MsLogoLib/MsLogoLib.inf #point to MsLogoLib - BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf - SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf - MsPlatBdsLib|MsvmPkg/Library/MsPlatBdsLib/MsPlatBdsLib.inf - - # - # MsGraphicsPkg Libs - # - UIToolKitLib|MsGraphicsPkg/Library/SimpleUIToolKit/SimpleUIToolKit.inf - MsColorTableLib|MsGraphicsPkg/Library/MsColorTableLib/MsColorTableLib.inf - MsUiThemeCopyLib|MsGraphicsPkg/Library/MsUiThemeCopyLib/MsUiThemeCopyLib.inf - PlatformThemeLib|MsvmPkg/Library/PlatformThemeLib/PlatformThemeLib.inf - SwmDialogsLib|MsGraphicsPkg/Library/SwmDialogsLib/SwmDialogs.inf - - MsUiThemeLib|MsGraphicsPkg/Library/MsUiThemeLib/Dxe/MsUiThemeLib.inf - - # - # Platform Runtime Package (PRM) Libs - # - PrmContextBufferLib|PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf - PrmModuleDiscoveryLib|PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf - PrmPeCoffLib|PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf + +################################################################################ +# +# SKU Identification section - list of all SKU IDs supported by this Platform. +# +################################################################################ +[SkuIds] + 0|DEFAULT + +################################################################################ +# +# Library Class section +# +# Library class names used by this platform and the implementations of those +# libraries. | +# +################################################################################ + +# +# Library instances to use by default for all modules and phases unless overridden below +# +[LibraryClasses] + AdvancedLoggerAccessLib|AdvLoggerPkg/Library/AdvancedLoggerAccessLib/AdvancedLoggerAccessLib.inf + AdvancedLoggerHdwPortLib|AdvLoggerPkg/Library/AdvancedLoggerHdwPortLib/AdvancedLoggerHdwPortLib.inf + ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf + ArmMmuLib|UefiCpuPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf + ArmMonitorLib|ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf + ArmSmcLib|MdePkg/Library/ArmSmcLib/ArmSmcLib.inf + ArmTrngLib|MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf + AssertLib|AdvLoggerPkg/Library/AssertLib/AssertLib.inf + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + BiosDeviceLib|MsvmPkg/Library/BiosDeviceLib/BiosDeviceLib.inf + CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + CrashLib|MsvmPkg/Library/CrashLib/CrashLib.inf + CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf + CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf + DebugLib|AdvLoggerPkg/Library/BaseDebugLibAdvancedLogger/BaseDebugLibAdvancedLogger.inf + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + DefaultExceptionHandlerLib|MsvmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf + DeviceStateLib|MdeModulePkg/Library/DeviceStateLib/DeviceStateLib.inf + DisplayDeviceStateLib|MsGraphicsPkg/Library/ColorBarDisplayDeviceStateLib/ColorBarDisplayDeviceStateLib.inf + EmclLib|MsvmPkg/Library/EmclLib/EmclLib.inf + FltUsedLib|MsCorePkg/Library/FltUsedLib/FltUsedLib.inf + FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf + Hash2CryptoLib|SecurityPkg/Library/DxeHash2CryptoLib/DxeHash2CryptoLib.inf + HwResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf + ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf + IsolationLib|MsvmPkg/Library/IsolationLib/IsolationLib.inf + MathLib|MsCorePkg/Library/MathLib/MathLib.inf + MmuLib|ArmPkg/Library/MmuLib/BaseMmuLib.inf + MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf + MsBaseLib|MsvmPkg/Library/MsBaseLib/MsBaseLib.inf + MsBootPolicyLib|MsvmPkg/Library/MsBootPolicyLib/MsBootPolicyLib.inf + OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf + PanicLib|MdePkg/Library/BasePanicLibNull/BasePanicLibNull.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf + PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf + ResetUtilityLib|MdeModulePkg/Library/ResetUtilityLib/ResetUtilityLib.inf + SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf + StackCheckFailureHookLib|MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf + StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf + SecurityLockAuditLib|MdeModulePkg/Library/SecurityLockAuditDebugMessageLib/SecurityLockAuditDebugMessageLib.inf ##MSCHANGE + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf + Tpm2HelpLib|SecurityPkg/Library/Tpm2HelpLib/Tpm2HelpLib.inf + TimerLib|MsvmPkg/Library/HvTimerLib/HvTimerLib.inf + UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf + UiRectangleLib|MsGraphicsPkg/Library/BaseUiRectangleLib/BaseUiRectangleLib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf + +!if $(DEBUGLIB_SERIAL) == 1 + SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf + PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf +!endif + + ## MS_CHANGE_? + # MeasuredBoot and Other TPM-Based Security + Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf + Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf + TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf + Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf + Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf + OemTpm2InitLib|SecurityPkg/Library/OemTpm2InitLibNull/OemTpm2InitLib.inf ## MS_CHANGE_? + Tcg2PreUefiEventLogLib|SecurityPkg/Library/Tcg2PreUefiEventLogLibNull/Tcg2PreUefiEventLogLibNull.inf + ## MS_CHANGE_? + + # MsCore BDS & FrontPage Libs + PlatformBootManagerLib|MsCorePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf + DeviceBootManagerLib|MsvmPkg/Library/DeviceBootManagerLib/DeviceBootManagerLib.inf + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + MsLogoLib|MsvmPkg/Library/MsLogoLib/MsLogoLib.inf #point to MsLogoLib + BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + MsPlatBdsLib|MsvmPkg/Library/MsPlatBdsLib/MsPlatBdsLib.inf + + # + # MsGraphicsPkg Libs + # + UIToolKitLib|MsGraphicsPkg/Library/SimpleUIToolKit/SimpleUIToolKit.inf + MsColorTableLib|MsGraphicsPkg/Library/MsColorTableLib/MsColorTableLib.inf + MsUiThemeCopyLib|MsGraphicsPkg/Library/MsUiThemeCopyLib/MsUiThemeCopyLib.inf + PlatformThemeLib|MsvmPkg/Library/PlatformThemeLib/PlatformThemeLib.inf + SwmDialogsLib|MsGraphicsPkg/Library/SwmDialogsLib/SwmDialogs.inf + + MsUiThemeLib|MsGraphicsPkg/Library/MsUiThemeLib/Dxe/MsUiThemeLib.inf + + # + # Platform Runtime Package (PRM) Libs + # + PrmContextBufferLib|PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf + PrmModuleDiscoveryLib|PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf + PrmPeCoffLib|PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf # memcpy and memset are difficult to avoid, esp. on ARM64. # e.g. struct/union/array init/assign, passing va_list by value in PrintLib. @@ -191,816 +192,820 @@ # Current upstream AMD64 CompilerIntrinsicsLib does not compile but future does. [LibraryClasses.AARCH64] NULL|MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf - -# -# Library instance overrides for SEC and PEI -# -[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM] - ArmMmuLib|UefiCpuPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf - ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf - MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf - PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf - PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf - StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf - -# -# Library instance overrides just for SEC -# -[LibraryClasses.common.SEC] - DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf - -# -# Library instance overrides for PEI -# -[LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM] - FrameBufferMemDrawLib|MsGraphicsPkg/Library/FrameBufferMemDrawLib/FrameBufferMemDrawLibPei.inf - HvHypercallLib|MsvmPkg/Library/HvHypercallLib/PeiHvHypercallLib.inf - HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf - OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf - PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf - WatchdogTimerLib|MsvmPkg/Library/WatchdogTimerLib/WatchdogTimerLib.inf - ResetSystemLib|MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf - -# -# Library instance overrides just for PEI CORE -# -[LibraryClasses.common.PEI_CORE] - AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/PeiCore/AdvancedLoggerLib.inf - PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf - -# -# Library instance overrides just for PEIMs -# -[LibraryClasses.common.PEIM] - AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/Pei/AdvancedLoggerLib.inf - DebugLib|AdvLoggerPkg/Library/PeiDebugLibAdvancedLogger/PeiDebugLibAdvancedLogger.inf - PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf - ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf - PcdDatabaseLoaderLib|MdeModulePkg/Library/PcdDatabaseLoaderLib/Pei/PcdDatabaseLoaderLibPei.inf # MU_CHANGE - RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf - - MsUiThemeLib|MsGraphicsPkg/Library/MsUiThemeLib/Pei/MsUiThemeLib.inf - - -# -# Library instance overrides for DXE -# -[LibraryClasses.common.DXE_CORE, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION] - BootEventLogLib|MsvmPkg/Library/BootEventLogLib/BootEventLogLib.inf - ConfigLib|MsvmPkg/Library/ConfigLib/ConfigLib.inf - DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf - DpcLib|NetworkPkg/Library/DxeDpcLib/DxeDpcLib.inf - DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf - DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf - DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf - EventLogLib|MsvmPkg/Library/EventLogLib/EventLogLib.inf - ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf - FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf - FrameBufferMemDrawLib|MsGraphicsPkg/Library/FrameBufferMemDrawLib/FrameBufferMemDrawLibDxe.inf - HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf - HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf - HttpLib|NetworkPkg/Library/DxeHttpLib/DxeHttpLib.inf - IpIoLib|NetworkPkg/Library/DxeIpIoLib/DxeIpIoLib.inf - MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf - MemoryTypeInformationChangeLib|MdeModulePkg/Library/MemoryTypeInformationChangeLibNull/MemoryTypeInformationChangeLibNull.inf - MmioAllocationLib|MsvmPkg/Library/MmioAllocationLib/MmioAllocationLib.inf - NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf - PcdDatabaseLoaderLib|MdeModulePkg/Library/PcdDatabaseLoaderLib/Dxe/PcdDatabaseLoaderLibDxe.inf # MU_CHANGE - PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf - ResetSystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSystemLib.inf - RngLib|MsvmPkg/Library/MsvmRngLib/MsvmRngLib.inf - SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf - UdpIoLib|NetworkPkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf - UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf - UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf - UefiLib|MdePkg/Library/UefiLib/UefiLib.inf - UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf - WatchdogTimerLib|MsvmPkg/Library/WatchdogTimerLib/WatchdogTimerLib.inf - PciSegmentLib|MdePkg/Library/PciSegmentLibSegmentInfo/BasePciSegmentLibSegmentInfo.inf - PciSegmentInfoLib|MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.inf - IoMmuLib|MdeModulePkg/Library/IoMmuLibNull/IoMmuLibNull.inf - -# -# Library instances overrides for just DXE CORE -# -[LibraryClasses.common.DXE_CORE] - AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/DxeCore/AdvancedLoggerLib.inf - DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf - HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf - MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf - HvHypercallLib|MsvmPkg/Library/HvHypercallLib/HvHypercallLib.inf -##MSChange Begin -[LibraryClasses.common.DXE_DRIVER] - ResetSystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSystemLib.inf - HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf - PolicyLib|PolicyServicePkg/Library/DxePolicyLib/DxePolicyLib.inf -##MSChange End - Tcg2PhysicalPresencePromptLib|MsvmPkg/Library/Tcg2PhysicalPresencePromptLibApprove/Tcg2PhysicalPresencePromptLibApprove.inf ## MS_CHANGE - PciHostBridgeLib|MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf - -# -# Library instance overrides for all DXE Drivers -# -[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER] - HvHypercallLib|MsvmPkg/Library/HvHypercallLib/HvHypercallLib.inf - UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf - -# -# Library instance overrides for DXE Drivers and Applications -# -[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION] - AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/Dxe/AdvancedLoggerLib.inf - -# -# Library instance overrides for just DXE Runtime Drivers -# -[LibraryClasses.common.DXE_RUNTIME_DRIVER] - AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/Runtime/AdvancedLoggerLib.inf - BiosDeviceLib|MsvmPkg/Library/BiosDeviceLib/BiosDeviceRuntimeLib.inf - # runtime drivers shouldn't use UEFI debugging, especially after ExitBootServices() - DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf - ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf - ResetSystemLib|MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.inf - UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf - -# PERF MODULES START -!if $(PERF_TRACE_ENABLE) == TRUE -[PcdsFixedAtBuild] - # Sets bits 0, 3 to enable measurement but skip binding supports - gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x9 - # 16M should be enough to fit all the verbose measurements - gEfiMdeModulePkgTokenSpaceGuid.PcdExtFpdtBootRecordPadSize|0x1000000 - -[LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM] - PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf - -[LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_DRIVER] - PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf - -[LibraryClasses.common.DXE_CORE] - PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf - -# [Components.common] -# # FBPT Dump App: -# # Note, this has a dependency on ShellLib, so can only build this if also building the shell -# PerformancePkg/Application/FbptDump/FbptDump.inf -!else -[LibraryClasses.common] - PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf -!endif -# PERF MODULES END - -[PcdsFixedAtBuild.common] - # Advanced Logger Config - gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerPreMemPages|1 # Size is 4KB - gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerPages|1024 # Size is 4MB -!if $(DEBUGLIB_SERIAL) == 1 - !ifdef DEBUG_NOISY - # This enables verbose output - gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerHdwPortDebugPrintErrorLevel|0x804FEF4B - !else - # This default turns on errors and warnings - gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerHdwPortDebugPrintErrorLevel|0x80000002 - !endif -!else - # We do not want anything out of serial if the flag is not provided - gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerHdwPortDebugPrintErrorLevel|0x0 -!endif - - # Feature Debugger Config - DebuggerFeaturePkgTokenSpaceGuid.PcdInitialBreakpointTimeoutMs|0 -!if $(DEBUGGER_ENABLED) == 1 - DebuggerFeaturePkgTokenSpaceGuid.PcdForceEnableDebugger|TRUE -!endif - - # Synthetic Timer Config - gMsvmPkgTokenSpaceGuid.PcdSynicTimerSintIndex|0x1 - gMsvmPkgTokenSpaceGuid.PcdSynicTimerTimerIndex|0x0 - gMsvmPkgTokenSpaceGuid.PcdSynicTimerVector|17 # use PPI for SINTs - gMsvmPkgTokenSpaceGuid.PcdSynicTimerDefaultPeriod|100000 - - # Vmbus Config - gMsvmPkgTokenSpaceGuid.PcdVmbusSintVector|18 # use PPI for SINTs - gMsvmPkgTokenSpaceGuid.PcdVmbusSintIndex|0x2 - # PPI for Linux. Older public kernels used by WSL2 had 16 and 17 hardcoded, so - # use the next available, 18. - gMsvmPkgTokenSpaceGuid.PcdVmbusVector|18 - - # BIOS Device - gMsvmPkgTokenSpaceGuid.PcdBiosBaseAddress|0xEFFED000 - - # Generation Counter Device - gMsvmPkgTokenSpaceGuid.PcdGenCountEventVector|35 # SPI - - # Battery Device - gMsvmPkgTokenSpaceGuid.PcdBatteryBase|0xEFFEA000 - gMsvmPkgTokenSpaceGuid.PcdBatteryEventVector|36 # SPI - - # UART Devices - gMsvmPkgTokenSpaceGuid.PcdCom1RegisterBase|0xEFFEC000 - gMsvmPkgTokenSpaceGuid.PcdCom1Vector|33 # SPI - gMsvmPkgTokenSpaceGuid.PcdCom2RegisterBase|0xEFFEB000 - gMsvmPkgTokenSpaceGuid.PcdCom2Vector|34 # SPI - - # RTC (clock) - gMsvmPkgTokenSpaceGuid.PcdRtcRegisterBase|0x70 - gMsvmPkgTokenSpaceGuid.PcdRtcVector|8 - - # PMEM (NVDIMM) - gMsvmPkgTokenSpaceGuid.PcdPmemRegisterBase|0xEFFE9000 - gMsvmPkgTokenSpaceGuid.PcdPmemEventVector|37 # SPI - - # Networking - gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE - - # Processor Aggregator - gMsvmPkgTokenSpaceGuid.PcdProcIdleBase|0xEFFE8000 - gMsvmPkgTokenSpaceGuid.PcdProcIdleEventVector|38 # SPI - - # Networking - gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|FALSE #Opt out of secure RNG until ARM64 has a way of doing TRNG. - - # GTDT for AArch64. Currently these aren't exposed to guests, and 0 is a valid - # value to configure. Linux will attempt to configure them, so assign valid - # interrupt lines. - gMsvmPkgTokenSpaceGuid.PcdNonSecureEL1TimerGSIV|19 - gMsvmPkgTokenSpaceGuid.PcdVirtualEL1TimerGSIV|20 - gMsvmPkgTokenSpaceGuid.PcdNonSecureEL2TimerGSIV|21 - - # - # Static initial memory config - presumes minimum 64MB in VM - # Page table, stack, and heap are hard-coded in host worker process. - # ARM uses 128KB for stack and heap because it uses 4k pages which leads - # to more entries in the translation table. - # - # Firmware: 0x00000000 to 0x00800000 8MB (Pcds from FDF file) - # PageTable: 0x00800000 to 0x00804000 4KB (starts on 2MB boundary) - # Stack and Heap: 0x00804000 to 0x00824000 128KB - # System Memory (PEI): 0x00824000 to 0x04000000 ~55MB - # - gMsvmPkgTokenSpaceGuid.PcdSystemMemoryBaseAddress|0x00824000 - gMsvmPkgTokenSpaceGuid.PcdSystemMemorySize|0x037EC000 - - # - # The runtime state of this PCD can be modified in the debugger by - # modifying EfiBdDebugPrintGlobalMask and EfiBdDebugPrintComponentMask. - # - # We now expect the host bios device to parse the in-memory advanced logger - # buffer to our tracing facilities - # - # NOTE: Additional debug levels may cause the in-memory advanced logger - # buffer to exceed its defined limit (see PcdAdvancedLoggerPages) - # - gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x804FEF4B - -# Disable asserts when not building debug -!if $(TARGET) == DEBUG - gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x47 -!else - gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x06 -!endif - - # - # See REPORT_STATUS_CODE_PROPERTY_nnnnn in ReportStatusCodeLib.h - # - gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x00000007 - - # Prevent reboots due to some memory variables being out of sync, seems - # to only be relevant when supporting S4 (hibernate) - # FUTURE: figure out what this is all about - gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE - - # Support SMBIOS 3.1 - gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0301 - - # Default OEM ID for ACPI table creation, its length must be 0x6 bytes to follow ACPI specification. - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"VRTUAL" - - # Default OEM Table ID for ACPI table creation, "MICROSFT", as a SIGNATURE_64 value. - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x5446534F5243494D - - # Default OEM Revision for ACPI table creation. - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision|0x00000001 - - # Default Creator ID for ACPI table creation, "MSFT", as a SIGNATURE_32 value. - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x5446534D - - # Default Creator Revision for ACPI table creation. - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x00000001 - - # COM port used for feature debugger - gMsvmPkgTokenSpaceGuid.PcdFeatureDebuggerPortUartBase|0xEFFEC000 #COM1 - - # COM port used for advanced logger output - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0xEFFEB000 #COM2 - - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200 - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8 - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1 - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1 - - # Default setting for serial console terminal type is UTF8 - gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|3 - - # Override defaults to indicate only US english support - gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangCodes|"engeng" - gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes|"en;en-US" - - # Base addresses of memory mapped devices in MMIO space. - gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0xFED40000 - - # Disable TPM platform hierarchy by default - gEfiSecurityPkgTokenSpaceGuid.PcdRandomizePlatformHierarchy|FALSE - - # Disable front page auto power off - gMsGraphicsPkgTokenSpaceGuid.PcdPowerOffDelay|0xffffffff - - # Change PcdBootManagerMenuFile to point to the FrontPage application - gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x8A, 0x70, 0x42, 0x40, 0x2D, 0x0F, 0x23, 0x48, 0xAC, 0x60, 0x0D, 0x77, 0xB3, 0x11, 0x18, 0x89 } - - gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerInBootOrder|FALSE - -[PcdsFeatureFlag.common] - gEfiMdeModulePkgTokenSpaceGuid.PcdInternalEventServicesEnabled|TRUE - - gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerFixedInRAM|FALSE - gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedFileLoggerForceEnable|TRUE - -[PcdsDynamicDefault] - # GIC related config (legacy Hyper-V values as default) - gArmTokenSpaceGuid.PcdGicDistributorBase|0xFFFF0000 # aka GICD - gArmTokenSpaceGuid.PcdGicRedistributorsBase|0xEFFEE000 # aka GICR - - gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE - gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE - gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformRecoverySupport|FALSE - - gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0x0 - - gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType|4 # 04 = UUID-Based DHCPv6 Unique Identifier (DUID-UUID) - - # UEFI Config information from the BiosDevice - # UEFI_CONFIG_STRUCTURE_COUNT - gMsvmPkgTokenSpaceGuid.PcdConfigBlobSize|0x0 - # UEFI_CONFIG_BIOS_INFORMATION - gMsvmPkgTokenSpaceGuid.PcdLegacyMemoryMap|0x0 - - # UEFI_CONFIG_MADT - gMsvmPkgTokenSpaceGuid.PcdMadtPtr|0x0 - gMsvmPkgTokenSpaceGuid.PcdMadtSize|0x0 - - # UEFI_CONFIG_SRAT - gMsvmPkgTokenSpaceGuid.PcdSratPtr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSratSize|0x0 - - # UEFI_CONFIG_SLIT - gMsvmPkgTokenSpaceGuid.PcdSlitPtr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSlitSize|0x0 - - # UEFI_CONFIG_PPTT - gMsvmPkgTokenSpaceGuid.PcdPpttPtr|0x0 - gMsvmPkgTokenSpaceGuid.PcdPpttSize|0x0 - - # UEFI_CONFIG_MCFG - gMsvmPkgTokenSpaceGuid.PcdMcfgPtr|0x0 - gMsvmPkgTokenSpaceGuid.PcdMcfgSize|0x0 - - # UEFI_CONFIG_SSDT - gMsvmPkgTokenSpaceGuid.PcdSsdtPtr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSsdtSize|0x0 - - # UEFI_CONFIG_HMAT - gMsvmPkgTokenSpaceGuid.PcdHmatPtr|0x0 - gMsvmPkgTokenSpaceGuid.PcdHmatSize|0x0 - - # UEFI_CONFIG_IORT - gMsvmPkgTokenSpaceGuid.PcdIortPtr|0x0 - gMsvmPkgTokenSpaceGuid.PcdIortSize|0x0 - - # UEFI_CONFIG_MEMORY_MAP - gMsvmPkgTokenSpaceGuid.PcdMemoryMapPtr|0x0 - gMsvmPkgTokenSpaceGuid.PcdMemoryMapSize|0x0 - - # UEFI_CONFIG_ENTROPY - # Points to the actual entropy array, not the containing config structure - gMsvmPkgTokenSpaceGuid.PcdEntropyPtr|0x0 - - # UEFI_CONFIG_BIOS_GUID - # Points to the actual GUID, not the containing config structure - gMsvmPkgTokenSpaceGuid.PcdBiosGuidPtr|0x0 - - # UEFI_CONFIG_SMBIOS_SYSTEM_MANUFACTURER - # Points to a null terminated string of the specified size - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemManufacturerStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemManufacturerSize|0x0 - - # UEFI_CONFIG_SMBIOS_SYSTEM_PRODUCT_NAME - # Points to a null terminated string of the specified size - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemProductNameStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemProductNameSize|0x0 - - # UEFI_CONFIG_SMBIOS_SYSTEM_VERSION - # Points to a null terminated string of the specified size - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemVersionStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemVersionSize|0x0 - - # UEFI_CONFIG_SMBIOS_SYSTEM_SERIAL_NUMBER - # Points to a null terminated string of the specified size - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemSerialNumberStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemSerialNumberSize|0x0 - - # UEFI_CONFIG_SMBIOS_SYSTEM_SKU_NUMBER - # Points to a null terminated string of the specified size - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemSKUNumberStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemSKUNumberSize|0x0 - - # UEFI_CONFIG_SMBIOS_SYSTEM_FAMILY - # Points to a null terminated string of the specified size - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemFamilyStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemFamilySize|0x0 - - # UEFI_CONFIG_SMBIOS_BASE_SERIAL_NUMBER - gMsvmPkgTokenSpaceGuid.PcdSmbiosBaseSerialNumberStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosBaseSerialNumberSize|0x0 - - # UEFI_CONFIG_SMBIOS_CHASSIS_SERIAL_NUMBER - gMsvmPkgTokenSpaceGuid.PcdSmbiosChassisSerialNumberStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosChassisSerialNumberSize|0x0 - - # UEFI_CONFIG_SMBIOS_CHASSIS_ASSET_TAG - gMsvmPkgTokenSpaceGuid.PcdSmbiosChassisAssetTagStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosChassisAssetTagSize|0x0 - - # UEFI_CONFIG_SMBIOS_BIOS_LOCK_STRING - gMsvmPkgTokenSpaceGuid.PcdSmbiosBiosLockStringStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosBiosLockStringSize|0x0 - - # UEFI_CONFIG_SMBIOS_3_1_PROCESSOR_INFORMATION - # Defaults are set to Unknown unless otherwise noted - # Processor Type defaults to Central Processor type (CPU) - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorType|0x3 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorID|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorVoltage|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorExternalClock|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorMaxSpeed|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorCurrentSpeed|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorStatus|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorUpgrade|0x1 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorCharacteristics|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorFamily2|0x2 - - # UEFI_CONFIG_SMBIOS_SOCKET_DESIGNATION - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorSocketDesignationStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorSocketDesignationSize|0x0 - - # UEFI_CONFIG_SMBIOS_PROCESSOR_MANUFACTURER - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorManufacturerStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorManufacturerSize|0x0 - - # UEFI_CONFIG_SMBIOS_PROCESSOR_VERSION - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorVersionStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorVersionSize|0x0 - - # UEFI_CONFIG_SMBIOS_PROCESSOR_SERIAL_NUMBER - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorSerialNumberStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorSerialNumberSize|0x0 - - # UEFI_CONFIG_SMBIOS_PROCESSOR_ASSET_TAG - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorAssetTagStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorAssetTagSize|0x0 - - # UEFI_CONFIG_SMBIOS_PROCESSOR_PART_NUMBER - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorPartNumberStr|0x0 - gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorPartNumberSize|0x0 - - # UEFI_CONFIG_FLAGS - gMsvmPkgTokenSpaceGuid.PcdSerialControllersEnabled|FALSE - gMsvmPkgTokenSpaceGuid.PcdPauseAfterBootFailure|FALSE - gMsvmPkgTokenSpaceGuid.PcdPxeIpV6|FALSE - gMsvmPkgTokenSpaceGuid.PcdDebuggerEnabled|FALSE - gMsvmPkgTokenSpaceGuid.PcdLoadOempTable|FALSE - gMsvmPkgTokenSpaceGuid.PcdTpmEnabled|FALSE - gMsvmPkgTokenSpaceGuid.PcdHibernateEnabled|FALSE - gMsvmPkgTokenSpaceGuid.PcdConsoleMode|0x0 - gMsvmPkgTokenSpaceGuid.PcdMemoryAttributesTableEnabled|FALSE - gMsvmPkgTokenSpaceGuid.PcdVirtualBatteryEnabled|FALSE - gMsvmPkgTokenSpaceGuid.PcdSgxMemoryEnabled|FALSE - gMsvmPkgTokenSpaceGuid.PcdProcIdleEnabled|FALSE - gMsvmPkgTokenSpaceGuid.PcdCxlMemoryEnabled|FALSE - gMsvmPkgTokenSpaceGuid.PcdIsVmbfsBoot|FALSE - gMsvmPkgTokenSpaceGuid.PcdDisableFrontpage|FALSE - gMsvmPkgTokenSpaceGuid.PcdMediaPresentEnabledByDefault|FALSE - gMsvmPkgTokenSpaceGuid.PcdEnableIMCWhenIsolated|FALSE - gMsvmPkgTokenSpaceGuid.PcdWatchdogEnabled|FALSE - gMsvmPkgTokenSpaceGuid.PcdHostEmulatorsWhenHardwareIsolated|FALSE - gMsvmPkgTokenSpaceGuid.PcdTpmLocalityRegsEnabled|FALSE - - # UEFI_CONFIG_PROCESSOR_INFORMATION - gMsvmPkgTokenSpaceGuid.PcdProcessorCount|0x0 - gMsvmPkgTokenSpaceGuid.PcdProcessorsPerVirtualSocket|0x0 - gMsvmPkgTokenSpaceGuid.PcdThreadsPerProcessor|0x0 - - # UEFI_CONFIG_MMIO_DESCRIPTION - # Currently only two mmio holes, low gap and high gap but we could - # do more in the future. - gMsvmPkgTokenSpaceGuid.PcdLowMmioGapBasePageNumber|0x0 - gMsvmPkgTokenSpaceGuid.PcdLowMmioGapSizeInPages|0x0 - gMsvmPkgTokenSpaceGuid.PcdHighMmioGapBasePageNumber|0x0 - gMsvmPkgTokenSpaceGuid.PcdHighMmioGapSizeInPages|0x0 - - # UEFI_CONFIG_ACPI_TABLE - gMsvmPkgTokenSpaceGuid.PcdAcpiTablePtr|0x0 - gMsvmPkgTokenSpaceGuid.PcdAcpiTableSize|0x0 - - # PcdTpm2HashMask - # This mask is used to indicate which PCRs are intended to be supported by the *platform* (not UEFI software). - # If a PCR is allocated that isn't in this mask, it will be deallocated by Tcg2Pei. - # If a PCR is supported in this mask, but isn't supported by the TPM, the mask will be updated by Tcg2Pei. - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0x00000007 # HASH_ALG_SHA[384 | 256 | 1] - - # PcdTcg2HashAlgorithmBitmap - # This bitmap is updated at runtime by HashLibBaseCryptoRouter. - # It indicates the UEFI at boot with the current FW support for TPM PCR hashing algorithms. - # For this implementation, we promise no support beyond what is provided by the HashLib instances. - gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap|0x00000000 - - # Default TCG2 stack will try to autodect TPM at startup. - # Fix this to dTPM 2.0 and skip the autodetection. - gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x5a, 0xf2, 0x6b, 0x28, 0xc3, 0xc2, 0x8c, 0x40, 0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, 0x17} - - ## This PCD defines minimum length(in bytes) of the system preboot TCG event log area(LAML). - # For PC Client Implementation spec up to and including 1.2 the minimum log size is 64KB. - # Increase to 128KB since Linux is measuring more information causing the 64KB buffer to run out. - # @Prompt Minimum length(in bytes) of the system preboot TCG event log area(LAML). - gEfiSecurityPkgTokenSpaceGuid.PcdTcgLogAreaMinLen|0x20000 - - # UEFI_CONFIG_NVDIMM_COUNT - gMsvmPkgTokenSpaceGuid.PcdNvdimmCount|0x0 - - # Isolation configuration - gMsvmPkgTokenSpaceGuid.PcdIsolationArchitecture|0x0 - gMsvmPkgTokenSpaceGuid.PcdIsolationParavisorPresent|FALSE - gMsvmPkgTokenSpaceGuid.PcdIsolationSharedGpaBoundary|0x0 - gMsvmPkgTokenSpaceGuid.PcdIsolationSharedGpaCanonicalizationBitmask|0x0 - - # UEFI_CONFIG_PCIE_BAR_APERTURES - gMsvmPkgTokenSpaceGuid.PcdPcieBarAperturesPtr|0 - gMsvmPkgTokenSpaceGuid.PcdPcieBarAperturesSize|0 - -################################################################################ -# -# Components Section - list of all Modules include for this Platform. -# -################################################################################ - -!include $(SHARED_CRYPTO_PATH)/Driver/Bin/CryptoDriver.inc.dsc - -[Components] - # - # SEC Phase modules - # - MsvmPkg/Sec/SecMain.inf - - # - # PEI Phase modules - # - ArmPkg/Drivers/CpuPei/CpuPei.inf - MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf - MdeModulePkg/Core/Pei/PeiMain.inf - MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf - MdeModulePkg/Universal/PCD/Pei/Pcd.inf - MsvmPkg/PlatformPei/PlatformPei.inf - MsGraphicsPkg/MsUiTheme/Pei/MsUiThemePpi.inf - SecurityPkg/RandomNumberGenerator/RngPei/RngPei.inf { - - RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf - } - - DebuggerFeaturePkg/DebugConfigPei/DebugConfigPei.inf - - # - # DXE Phase modules - # - ArmPkg/Drivers/CpuDxe/CpuDxe.inf - ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf - FatPkg/EnhancedFatDxe/Fat.inf - - MdeModulePkg/Universal/BdsDxe/BdsDxe.inf - MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf - MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf - MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf - UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf - MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf - MdeModulePkg/Core/Dxe/DxeMain.inf { - - NULL|MsCorePkg/Library/DebugPortProtocolInstallLib/DebugPortProtocolInstallLib.inf - ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf - DebugTransportLib|MsvmPkg/Library/DebugTransportLibMsvm/DebugTransportLibMsvm.inf - DebugAgentLib|DebuggerFeaturePkg/Library/DebugAgent/DebugAgentDxe.inf - PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf - SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf - TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf - TransportLogControlLib|DebuggerFeaturePkg/Library/TransportLogControlLibNull/TransportLogControlLibNull.inf - } - MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf - MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf - MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf - MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf { - - CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf - LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf - } - MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf - MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf - MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf { - - UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf - HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf - - gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1024 - gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|768 - gEfiMdeModulePkgTokenSpaceGuid.PcdSetGraphicsConsoleModeOnStart|FALSE - } - MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf - MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf - MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf - MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf - MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf - MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf - MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf - MdeModulePkg/Universal/Metronome/Metronome.inf - MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf - MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf - MdeModulePkg/Universal/PCD/Dxe/Pcd.inf - MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf - MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf { - - SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf - NULL|MsvmPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf - NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf - } - MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf - MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf - - MsGraphicsPkg/DisplayEngineDxe/DisplayEngineDxe.inf - - # Networking components - - NetworkPkg/ArpDxe/ArpDxe.inf - NetworkPkg/Dhcp4Dxe/Dhcp4Dxe.inf - NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf - NetworkPkg/DnsDxe/DnsDxe.inf - NetworkPkg/DpcDxe/DpcDxe.inf - NetworkPkg/HttpDxe/HttpDxe.inf - NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf - NetworkPkg/Ip4Dxe/Ip4Dxe.inf - NetworkPkg/Ip6Dxe/Ip6Dxe.inf - NetworkPkg/MnpDxe/MnpDxe.inf - NetworkPkg/Mtftp4Dxe/Mtftp4Dxe.inf - NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf - NetworkPkg/TcpDxe/TcpDxe.inf - NetworkPkg/TlsDxe/TlsDxe.inf - NetworkPkg/Udp4Dxe/Udp4Dxe.inf - NetworkPkg/Udp6Dxe/Udp6Dxe.inf - NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf - - MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf - MsvmPkg/AcpiTables/AcpiTables.inf - MsvmPkg/AziHsmDxe/AziHsmDxe.inf - MsvmPkg/EfiHvDxe/EfiHvDxe.inf - MsvmPkg/EmclDxe/EmclDxe.inf - MsvmPkg/EventLogDxe/EventLogDxe.inf - MsvmPkg/MsvmPcAtRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf - MsvmPkg/NetvscDxe/NetvscDxe.inf - MsvmPkg/NvmExpressDxe/NvmExpressDxe.inf - MsvmPkg/EfiDiagnosticsDxe/EfiDiagnosticsDxe.inf - MsvmPkg/PlatformDeviceStateHelper/PlatformDeviceStateHelper.inf - MsvmPkg/SerialDxe/SerialDxe.inf - MsvmPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf - MsvmPkg/StorvscDxe/StorvscDxe.inf - MsvmPkg/SynthKeyDxe/SynthKeyDxe.inf - MsvmPkg/SynicTimerDxe/SynicTimerDxe.inf - MsvmPkg/VariableDxe/VariableDxe.inf - MsvmPkg/VideoDxe/VideoDxe.inf - MsvmPkg/VmbfsDxe/VmbfsDxe.inf - MsvmPkg/VmbusDxe/VmbusDxe.inf - MsvmPkg/VmMeasurementDxe/VmMeasurementDxe.inf - MsvmPkg/VpcivscDxe/VpcivscDxe.inf - MsvmPkg/WatchdogTimerDxe/WatchdogTimerDxe.inf - - # Advanced logger components -!if $(FILE_LOGGER) == 1 - AdvLoggerPkg/AdvancedFileLogger/AdvancedFileLogger.inf -!endif - - SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf { - - RngLib|MsvmPkg/Library/MsvmRngLib/MsvmRngLib.inf - } - - # TPM related components - - SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf - - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf { - - Tpm2DeviceLib|MsvmPkg/Library/Tpm2DeviceLib/Tpm2DeviceLib.inf + +# +# Library instance overrides for SEC and PEI +# +[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM] + ArmMmuLib|UefiCpuPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf + ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf + +# +# Library instance overrides just for SEC +# +[LibraryClasses.common.SEC] + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + +# +# Library instance overrides for PEI +# +[LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM] + FrameBufferMemDrawLib|MsGraphicsPkg/Library/FrameBufferMemDrawLib/FrameBufferMemDrawLibPei.inf + HvHypercallLib|MsvmPkg/Library/HvHypercallLib/PeiHvHypercallLib.inf + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf + ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + WatchdogTimerLib|MsvmPkg/Library/WatchdogTimerLib/WatchdogTimerLib.inf + ResetSystemLib|MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf + +# +# Library instance overrides just for PEI CORE +# +[LibraryClasses.common.PEI_CORE] + AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/PeiCore/AdvancedLoggerLib.inf + PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf + +# +# Library instance overrides just for PEIMs +# +[LibraryClasses.common.PEIM] + AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/Pei/AdvancedLoggerLib.inf + DebugLib|AdvLoggerPkg/Library/PeiDebugLibAdvancedLogger/PeiDebugLibAdvancedLogger.inf + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf + PcdDatabaseLoaderLib|MdeModulePkg/Library/PcdDatabaseLoaderLib/Pei/PcdDatabaseLoaderLibPei.inf # MU_CHANGE + RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf + + MsUiThemeLib|MsGraphicsPkg/Library/MsUiThemeLib/Pei/MsUiThemeLib.inf + + +# +# Library instance overrides for DXE +# +[LibraryClasses.common.DXE_CORE, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION] + BootEventLogLib|MsvmPkg/Library/BootEventLogLib/BootEventLogLib.inf + ConfigLib|MsvmPkg/Library/ConfigLib/ConfigLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DpcLib|NetworkPkg/Library/DxeDpcLib/DxeDpcLib.inf + DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + EventLogLib|MsvmPkg/Library/EventLogLib/EventLogLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + FrameBufferMemDrawLib|MsGraphicsPkg/Library/FrameBufferMemDrawLib/FrameBufferMemDrawLibDxe.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + HttpLib|NetworkPkg/Library/DxeHttpLib/DxeHttpLib.inf + IoMmuLib|MdeModulePkg/Library/IoMmuLib/IoMmuLib.inf + IpIoLib|NetworkPkg/Library/DxeIpIoLib/DxeIpIoLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + MemoryTypeInformationChangeLib|MdeModulePkg/Library/MemoryTypeInformationChangeLibNull/MemoryTypeInformationChangeLibNull.inf + MmioAllocationLib|MsvmPkg/Library/MmioAllocationLib/MmioAllocationLib.inf + NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf + PcdDatabaseLoaderLib|MdeModulePkg/Library/PcdDatabaseLoaderLib/Dxe/PcdDatabaseLoaderLibDxe.inf # MU_CHANGE + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + ResetSystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSystemLib.inf + RngLib|MsvmPkg/Library/MsvmRngLib/MsvmRngLib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + UdpIoLib|NetworkPkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + WatchdogTimerLib|MsvmPkg/Library/WatchdogTimerLib/WatchdogTimerLib.inf + PciSegmentLib|MdePkg/Library/PciSegmentLibSegmentInfo/BasePciSegmentLibSegmentInfo.inf + PciSegmentInfoLib|MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.inf + +# +# Library instances overrides for just DXE CORE +# +[LibraryClasses.common.DXE_CORE] + AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/DxeCore/AdvancedLoggerLib.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf + MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + HvHypercallLib|MsvmPkg/Library/HvHypercallLib/HvHypercallLib.inf +##MSChange Begin +[LibraryClasses.common.DXE_DRIVER] + ResetSystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSystemLib.inf + HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf + PolicyLib|PolicyServicePkg/Library/DxePolicyLib/DxePolicyLib.inf +##MSChange End + Tcg2PhysicalPresencePromptLib|MsvmPkg/Library/Tcg2PhysicalPresencePromptLibApprove/Tcg2PhysicalPresencePromptLibApprove.inf ## MS_CHANGE + PciHostBridgeLib|MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf + +# +# Library instance overrides for all DXE Drivers +# +[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER] + HvHypercallLib|MsvmPkg/Library/HvHypercallLib/HvHypercallLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + +# +# Library instance overrides for DXE Drivers and Applications +# +[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION] + AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/Dxe/AdvancedLoggerLib.inf + +# +# Library instance overrides for just DXE Runtime Drivers +# +[LibraryClasses.common.DXE_RUNTIME_DRIVER] + AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/Runtime/AdvancedLoggerLib.inf + BiosDeviceLib|MsvmPkg/Library/BiosDeviceLib/BiosDeviceRuntimeLib.inf + # runtime drivers shouldn't use UEFI debugging, especially after ExitBootServices() + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + ResetSystemLib|MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.inf + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + +# PERF MODULES START +!if $(PERF_TRACE_ENABLE) == TRUE +[PcdsFixedAtBuild] + # Sets bits 0, 3 to enable measurement but skip binding supports + gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x9 + # 16M should be enough to fit all the verbose measurements + gEfiMdeModulePkgTokenSpaceGuid.PcdExtFpdtBootRecordPadSize|0x1000000 + +[LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM] + PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf + +[LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_DRIVER] + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + +[LibraryClasses.common.DXE_CORE] + PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf + +# [Components.common] +# # FBPT Dump App: +# # Note, this has a dependency on ShellLib, so can only build this if also building the shell +# PerformancePkg/Application/FbptDump/FbptDump.inf +!else +[LibraryClasses.common] + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf +!endif +# PERF MODULES END + +[PcdsFixedAtBuild.common] + # Advanced Logger Config + gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerPreMemPages|1 # Size is 4KB + gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerPages|1024 # Size is 4MB +!if $(DEBUGLIB_SERIAL) == 1 + !ifdef DEBUG_NOISY + # This enables verbose output + gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerHdwPortDebugPrintErrorLevel|0x804FEF4B + !else + # This default turns on errors and warnings + gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerHdwPortDebugPrintErrorLevel|0x80000002 + !endif +!else + # We do not want anything out of serial if the flag is not provided + gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerHdwPortDebugPrintErrorLevel|0x0 +!endif + + # Feature Debugger Config + DebuggerFeaturePkgTokenSpaceGuid.PcdInitialBreakpointTimeoutMs|0 +!if $(DEBUGGER_ENABLED) == 1 + DebuggerFeaturePkgTokenSpaceGuid.PcdForceEnableDebugger|TRUE +!endif + + # Synthetic Timer Config + gMsvmPkgTokenSpaceGuid.PcdSynicTimerSintIndex|0x1 + gMsvmPkgTokenSpaceGuid.PcdSynicTimerTimerIndex|0x0 + gMsvmPkgTokenSpaceGuid.PcdSynicTimerVector|17 # use PPI for SINTs + gMsvmPkgTokenSpaceGuid.PcdSynicTimerDefaultPeriod|100000 + + # Vmbus Config + gMsvmPkgTokenSpaceGuid.PcdVmbusSintVector|18 # use PPI for SINTs + gMsvmPkgTokenSpaceGuid.PcdVmbusSintIndex|0x2 + # PPI for Linux. Older public kernels used by WSL2 had 16 and 17 hardcoded, so + # use the next available, 18. + gMsvmPkgTokenSpaceGuid.PcdVmbusVector|18 + + # BIOS Device + gMsvmPkgTokenSpaceGuid.PcdBiosBaseAddress|0xEFFED000 + + # Generation Counter Device + gMsvmPkgTokenSpaceGuid.PcdGenCountEventVector|35 # SPI + + # Battery Device + gMsvmPkgTokenSpaceGuid.PcdBatteryBase|0xEFFEA000 + gMsvmPkgTokenSpaceGuid.PcdBatteryEventVector|36 # SPI + + # UART Devices + gMsvmPkgTokenSpaceGuid.PcdCom1RegisterBase|0xEFFEC000 + gMsvmPkgTokenSpaceGuid.PcdCom1Vector|33 # SPI + gMsvmPkgTokenSpaceGuid.PcdCom2RegisterBase|0xEFFEB000 + gMsvmPkgTokenSpaceGuid.PcdCom2Vector|34 # SPI + + # RTC (clock) + gMsvmPkgTokenSpaceGuid.PcdRtcRegisterBase|0x70 + gMsvmPkgTokenSpaceGuid.PcdRtcVector|8 + + # PMEM (NVDIMM) + gMsvmPkgTokenSpaceGuid.PcdPmemRegisterBase|0xEFFE9000 + gMsvmPkgTokenSpaceGuid.PcdPmemEventVector|37 # SPI + + # Networking + gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE + + # Processor Aggregator + gMsvmPkgTokenSpaceGuid.PcdProcIdleBase|0xEFFE8000 + gMsvmPkgTokenSpaceGuid.PcdProcIdleEventVector|38 # SPI + + # Networking + gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|FALSE #Opt out of secure RNG until ARM64 has a way of doing TRNG. + + # GTDT for AArch64. Currently these aren't exposed to guests, and 0 is a valid + # value to configure. Linux will attempt to configure them, so assign valid + # interrupt lines. + gMsvmPkgTokenSpaceGuid.PcdNonSecureEL1TimerGSIV|19 + gMsvmPkgTokenSpaceGuid.PcdVirtualEL1TimerGSIV|20 + gMsvmPkgTokenSpaceGuid.PcdNonSecureEL2TimerGSIV|21 + + # + # Static initial memory config - presumes minimum 64MB in VM + # Page table, stack, and heap are hard-coded in host worker process. + # ARM uses 128KB for stack and heap because it uses 4k pages which leads + # to more entries in the translation table. + # + # Firmware: 0x00000000 to 0x00800000 8MB (Pcds from FDF file) + # PageTable: 0x00800000 to 0x00804000 4KB (starts on 2MB boundary) + # Stack and Heap: 0x00804000 to 0x00824000 128KB + # System Memory (PEI): 0x00824000 to 0x04000000 ~55MB + # + gMsvmPkgTokenSpaceGuid.PcdSystemMemoryBaseAddress|0x00824000 + gMsvmPkgTokenSpaceGuid.PcdSystemMemorySize|0x037EC000 + + # + # The runtime state of this PCD can be modified in the debugger by + # modifying EfiBdDebugPrintGlobalMask and EfiBdDebugPrintComponentMask. + # + # We now expect the host bios device to parse the in-memory advanced logger + # buffer to our tracing facilities + # + # NOTE: Additional debug levels may cause the in-memory advanced logger + # buffer to exceed its defined limit (see PcdAdvancedLoggerPages) + # + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x804FEF4B + +# Disable asserts when not building debug +!if $(TARGET) == DEBUG + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x47 +!else + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x06 +!endif + + # + # See REPORT_STATUS_CODE_PROPERTY_nnnnn in ReportStatusCodeLib.h + # + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x00000007 + + # Prevent reboots due to some memory variables being out of sync, seems + # to only be relevant when supporting S4 (hibernate) + # FUTURE: figure out what this is all about + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE + + # Support SMBIOS 3.1 + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0301 + + # Default OEM ID for ACPI table creation, its length must be 0x6 bytes to follow ACPI specification. + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"VRTUAL" + + # Default OEM Table ID for ACPI table creation, "MICROSFT", as a SIGNATURE_64 value. + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x5446534F5243494D + + # Default OEM Revision for ACPI table creation. + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision|0x00000001 + + # Default Creator ID for ACPI table creation, "MSFT", as a SIGNATURE_32 value. + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x5446534D + + # Default Creator Revision for ACPI table creation. + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x00000001 + + # COM port used for feature debugger + gMsvmPkgTokenSpaceGuid.PcdFeatureDebuggerPortUartBase|0xEFFEC000 #COM1 + + # COM port used for advanced logger output + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0xEFFEB000 #COM2 + + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200 + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8 + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1 + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1 + + # Default setting for serial console terminal type is UTF8 + gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|3 + + # Override defaults to indicate only US english support + gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangCodes|"engeng" + gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes|"en;en-US" + + # Base addresses of memory mapped devices in MMIO space. + gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0xFED40000 + + # Disable TPM platform hierarchy by default + gEfiSecurityPkgTokenSpaceGuid.PcdRandomizePlatformHierarchy|FALSE + + # Disable front page auto power off + gMsGraphicsPkgTokenSpaceGuid.PcdPowerOffDelay|0xffffffff + + # Change PcdBootManagerMenuFile to point to the FrontPage application + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x8A, 0x70, 0x42, 0x40, 0x2D, 0x0F, 0x23, 0x48, 0xAC, 0x60, 0x0D, 0x77, 0xB3, 0x11, 0x18, 0x89 } + + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerInBootOrder|FALSE + +[PcdsFeatureFlag.common] + gEfiMdeModulePkgTokenSpaceGuid.PcdInternalEventServicesEnabled|TRUE + + gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerFixedInRAM|FALSE + gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedFileLoggerForceEnable|TRUE + +[PcdsDynamicDefault] + # GIC related config (legacy Hyper-V values as default) + gArmTokenSpaceGuid.PcdGicDistributorBase|0xFFFF0000 # aka GICD + gArmTokenSpaceGuid.PcdGicRedistributorsBase|0xEFFEE000 # aka GICR + + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformRecoverySupport|FALSE + + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0x0 + + gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType|4 # 04 = UUID-Based DHCPv6 Unique Identifier (DUID-UUID) + + # UEFI Config information from the BiosDevice + # UEFI_CONFIG_STRUCTURE_COUNT + gMsvmPkgTokenSpaceGuid.PcdConfigBlobSize|0x0 + # UEFI_CONFIG_BIOS_INFORMATION + gMsvmPkgTokenSpaceGuid.PcdLegacyMemoryMap|0x0 + + # UEFI_CONFIG_MADT + gMsvmPkgTokenSpaceGuid.PcdMadtPtr|0x0 + gMsvmPkgTokenSpaceGuid.PcdMadtSize|0x0 + + # UEFI_CONFIG_SRAT + gMsvmPkgTokenSpaceGuid.PcdSratPtr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSratSize|0x0 + + # UEFI_CONFIG_SLIT + gMsvmPkgTokenSpaceGuid.PcdSlitPtr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSlitSize|0x0 + + # UEFI_CONFIG_PPTT + gMsvmPkgTokenSpaceGuid.PcdPpttPtr|0x0 + gMsvmPkgTokenSpaceGuid.PcdPpttSize|0x0 + + # UEFI_CONFIG_MCFG + gMsvmPkgTokenSpaceGuid.PcdMcfgPtr|0x0 + gMsvmPkgTokenSpaceGuid.PcdMcfgSize|0x0 + + # UEFI_CONFIG_SSDT + gMsvmPkgTokenSpaceGuid.PcdSsdtPtr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSsdtSize|0x0 + + # UEFI_CONFIG_HMAT + gMsvmPkgTokenSpaceGuid.PcdHmatPtr|0x0 + gMsvmPkgTokenSpaceGuid.PcdHmatSize|0x0 + + # UEFI_CONFIG_IORT + gMsvmPkgTokenSpaceGuid.PcdIortPtr|0x0 + gMsvmPkgTokenSpaceGuid.PcdIortSize|0x0 + + # UEFI_CONFIG_MEMORY_MAP + gMsvmPkgTokenSpaceGuid.PcdMemoryMapPtr|0x0 + gMsvmPkgTokenSpaceGuid.PcdMemoryMapSize|0x0 + + # UEFI_CONFIG_ENTROPY + # Points to the actual entropy array, not the containing config structure + gMsvmPkgTokenSpaceGuid.PcdEntropyPtr|0x0 + + # UEFI_CONFIG_BIOS_GUID + # Points to the actual GUID, not the containing config structure + gMsvmPkgTokenSpaceGuid.PcdBiosGuidPtr|0x0 + + # UEFI_CONFIG_SMBIOS_SYSTEM_MANUFACTURER + # Points to a null terminated string of the specified size + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemManufacturerStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemManufacturerSize|0x0 + + # UEFI_CONFIG_SMBIOS_SYSTEM_PRODUCT_NAME + # Points to a null terminated string of the specified size + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemProductNameStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemProductNameSize|0x0 + + # UEFI_CONFIG_SMBIOS_SYSTEM_VERSION + # Points to a null terminated string of the specified size + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemVersionStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemVersionSize|0x0 + + # UEFI_CONFIG_SMBIOS_SYSTEM_SERIAL_NUMBER + # Points to a null terminated string of the specified size + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemSerialNumberStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemSerialNumberSize|0x0 + + # UEFI_CONFIG_SMBIOS_SYSTEM_SKU_NUMBER + # Points to a null terminated string of the specified size + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemSKUNumberStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemSKUNumberSize|0x0 + + # UEFI_CONFIG_SMBIOS_SYSTEM_FAMILY + # Points to a null terminated string of the specified size + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemFamilyStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosSystemFamilySize|0x0 + + # UEFI_CONFIG_SMBIOS_BASE_SERIAL_NUMBER + gMsvmPkgTokenSpaceGuid.PcdSmbiosBaseSerialNumberStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosBaseSerialNumberSize|0x0 + + # UEFI_CONFIG_SMBIOS_CHASSIS_SERIAL_NUMBER + gMsvmPkgTokenSpaceGuid.PcdSmbiosChassisSerialNumberStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosChassisSerialNumberSize|0x0 + + # UEFI_CONFIG_SMBIOS_CHASSIS_ASSET_TAG + gMsvmPkgTokenSpaceGuid.PcdSmbiosChassisAssetTagStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosChassisAssetTagSize|0x0 + + # UEFI_CONFIG_SMBIOS_BIOS_LOCK_STRING + gMsvmPkgTokenSpaceGuid.PcdSmbiosBiosLockStringStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosBiosLockStringSize|0x0 + + # UEFI_CONFIG_SMBIOS_3_1_PROCESSOR_INFORMATION + # Defaults are set to Unknown unless otherwise noted + # Processor Type defaults to Central Processor type (CPU) + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorType|0x3 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorID|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorVoltage|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorExternalClock|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorMaxSpeed|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorCurrentSpeed|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorStatus|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorUpgrade|0x1 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorCharacteristics|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorFamily2|0x2 + + # UEFI_CONFIG_SMBIOS_SOCKET_DESIGNATION + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorSocketDesignationStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorSocketDesignationSize|0x0 + + # UEFI_CONFIG_SMBIOS_PROCESSOR_MANUFACTURER + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorManufacturerStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorManufacturerSize|0x0 + + # UEFI_CONFIG_SMBIOS_PROCESSOR_VERSION + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorVersionStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorVersionSize|0x0 + + # UEFI_CONFIG_SMBIOS_PROCESSOR_SERIAL_NUMBER + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorSerialNumberStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorSerialNumberSize|0x0 + + # UEFI_CONFIG_SMBIOS_PROCESSOR_ASSET_TAG + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorAssetTagStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorAssetTagSize|0x0 + + # UEFI_CONFIG_SMBIOS_PROCESSOR_PART_NUMBER + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorPartNumberStr|0x0 + gMsvmPkgTokenSpaceGuid.PcdSmbiosProcessorPartNumberSize|0x0 + + # UEFI_CONFIG_FLAGS + gMsvmPkgTokenSpaceGuid.PcdSerialControllersEnabled|FALSE + gMsvmPkgTokenSpaceGuid.PcdPauseAfterBootFailure|FALSE + gMsvmPkgTokenSpaceGuid.PcdPxeIpV6|FALSE + gMsvmPkgTokenSpaceGuid.PcdDebuggerEnabled|FALSE + gMsvmPkgTokenSpaceGuid.PcdLoadOempTable|FALSE + gMsvmPkgTokenSpaceGuid.PcdTpmEnabled|FALSE + gMsvmPkgTokenSpaceGuid.PcdHibernateEnabled|FALSE + gMsvmPkgTokenSpaceGuid.PcdConsoleMode|0x0 + gMsvmPkgTokenSpaceGuid.PcdMemoryAttributesTableEnabled|FALSE + gMsvmPkgTokenSpaceGuid.PcdVirtualBatteryEnabled|FALSE + gMsvmPkgTokenSpaceGuid.PcdSgxMemoryEnabled|FALSE + gMsvmPkgTokenSpaceGuid.PcdProcIdleEnabled|FALSE + gMsvmPkgTokenSpaceGuid.PcdCxlMemoryEnabled|FALSE + gMsvmPkgTokenSpaceGuid.PcdIsVmbfsBoot|FALSE + gMsvmPkgTokenSpaceGuid.PcdDisableFrontpage|FALSE + gMsvmPkgTokenSpaceGuid.PcdMediaPresentEnabledByDefault|FALSE + gMsvmPkgTokenSpaceGuid.PcdEnableIMCWhenIsolated|FALSE + gMsvmPkgTokenSpaceGuid.PcdWatchdogEnabled|FALSE + gMsvmPkgTokenSpaceGuid.PcdHostEmulatorsWhenHardwareIsolated|FALSE + gMsvmPkgTokenSpaceGuid.PcdTpmLocalityRegsEnabled|FALSE + + # UEFI_CONFIG_PROCESSOR_INFORMATION + gMsvmPkgTokenSpaceGuid.PcdProcessorCount|0x0 + gMsvmPkgTokenSpaceGuid.PcdProcessorsPerVirtualSocket|0x0 + gMsvmPkgTokenSpaceGuid.PcdThreadsPerProcessor|0x0 + + # UEFI_CONFIG_MMIO_DESCRIPTION + # Currently only two mmio holes, low gap and high gap but we could + # do more in the future. + gMsvmPkgTokenSpaceGuid.PcdLowMmioGapBasePageNumber|0x0 + gMsvmPkgTokenSpaceGuid.PcdLowMmioGapSizeInPages|0x0 + gMsvmPkgTokenSpaceGuid.PcdHighMmioGapBasePageNumber|0x0 + gMsvmPkgTokenSpaceGuid.PcdHighMmioGapSizeInPages|0x0 + + # UEFI_CONFIG_ACPI_TABLE + gMsvmPkgTokenSpaceGuid.PcdAcpiTablePtr|0x0 + gMsvmPkgTokenSpaceGuid.PcdAcpiTableSize|0x0 + + # PcdTpm2HashMask + # This mask is used to indicate which PCRs are intended to be supported by the *platform* (not UEFI software). + # If a PCR is allocated that isn't in this mask, it will be deallocated by Tcg2Pei. + # If a PCR is supported in this mask, but isn't supported by the TPM, the mask will be updated by Tcg2Pei. + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0x00000007 # HASH_ALG_SHA[384 | 256 | 1] + + # PcdTcg2HashAlgorithmBitmap + # This bitmap is updated at runtime by HashLibBaseCryptoRouter. + # It indicates the UEFI at boot with the current FW support for TPM PCR hashing algorithms. + # For this implementation, we promise no support beyond what is provided by the HashLib instances. + gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap|0x00000000 + + # Default TCG2 stack will try to autodect TPM at startup. + # Fix this to dTPM 2.0 and skip the autodetection. + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x5a, 0xf2, 0x6b, 0x28, 0xc3, 0xc2, 0x8c, 0x40, 0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, 0x17} + + ## This PCD defines minimum length(in bytes) of the system preboot TCG event log area(LAML). + # For PC Client Implementation spec up to and including 1.2 the minimum log size is 64KB. + # Increase to 128KB since Linux is measuring more information causing the 64KB buffer to run out. + # @Prompt Minimum length(in bytes) of the system preboot TCG event log area(LAML). + gEfiSecurityPkgTokenSpaceGuid.PcdTcgLogAreaMinLen|0x20000 + + # UEFI_CONFIG_NVDIMM_COUNT + gMsvmPkgTokenSpaceGuid.PcdNvdimmCount|0x0 + + # Isolation configuration + gMsvmPkgTokenSpaceGuid.PcdIsolationArchitecture|0x0 + gMsvmPkgTokenSpaceGuid.PcdIsolationParavisorPresent|FALSE + gMsvmPkgTokenSpaceGuid.PcdIsolationSharedGpaBoundary|0x0 + gMsvmPkgTokenSpaceGuid.PcdIsolationSharedGpaCanonicalizationBitmask|0x0 + + # UEFI_CONFIG_PCIE_BAR_APERTURES + gMsvmPkgTokenSpaceGuid.PcdPcieBarAperturesPtr|0 + gMsvmPkgTokenSpaceGuid.PcdPcieBarAperturesSize|0 + +################################################################################ +# +# Components Section - list of all Modules include for this Platform. +# +################################################################################ + +!include $(SHARED_CRYPTO_PATH)/Driver/Bin/CryptoDriver.inc.dsc + +[Components] + # + # SEC Phase modules + # + MsvmPkg/Sec/SecMain.inf + + # + # PEI Phase modules + # + ArmPkg/Drivers/CpuPei/CpuPei.inf + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf + MdeModulePkg/Core/Pei/PeiMain.inf + MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf + MdeModulePkg/Universal/PCD/Pei/Pcd.inf + MsvmPkg/PlatformPei/PlatformPei.inf + MsGraphicsPkg/MsUiTheme/Pei/MsUiThemePpi.inf + SecurityPkg/RandomNumberGenerator/RngPei/RngPei.inf { + + RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf + } + + DebuggerFeaturePkg/DebugConfigPei/DebugConfigPei.inf + + # + # DXE Phase modules + # + ArmPkg/Drivers/CpuDxe/CpuDxe.inf + ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf + FatPkg/EnhancedFatDxe/Fat.inf + + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf + MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf + MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf + MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf + UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf + MdeModulePkg/Core/Dxe/DxeMain.inf { + + NULL|MsCorePkg/Library/DebugPortProtocolInstallLib/DebugPortProtocolInstallLib.inf + ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf + DebugTransportLib|MsvmPkg/Library/DebugTransportLibMsvm/DebugTransportLibMsvm.inf + DebugAgentLib|DebuggerFeaturePkg/Library/DebugAgent/DebugAgentDxe.inf + PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf + SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf + TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf + TransportLogControlLib|DebuggerFeaturePkg/Library/TransportLogControlLibNull/TransportLogControlLibNull.inf + } + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf + MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf { + + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf + } + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf { + + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1024 + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|768 + gEfiMdeModulePkgTokenSpaceGuid.PcdSetGraphicsConsoleModeOnStart|FALSE + } + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + MdeModulePkg/Universal/Metronome/Metronome.inf + MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf + MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf + MdeModulePkg/Universal/PCD/Dxe/Pcd.inf + MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf { + + SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + NULL|MsvmPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf + NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf + } + MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + + MsGraphicsPkg/DisplayEngineDxe/DisplayEngineDxe.inf + + # Security components + SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.inf + + # Networking components + + NetworkPkg/ArpDxe/ArpDxe.inf + NetworkPkg/Dhcp4Dxe/Dhcp4Dxe.inf + NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf + NetworkPkg/DnsDxe/DnsDxe.inf + NetworkPkg/DpcDxe/DpcDxe.inf + NetworkPkg/HttpDxe/HttpDxe.inf + NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf + NetworkPkg/Ip4Dxe/Ip4Dxe.inf + NetworkPkg/Ip6Dxe/Ip6Dxe.inf + NetworkPkg/MnpDxe/MnpDxe.inf + NetworkPkg/Mtftp4Dxe/Mtftp4Dxe.inf + NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf + NetworkPkg/TcpDxe/TcpDxe.inf + NetworkPkg/TlsDxe/TlsDxe.inf + NetworkPkg/Udp4Dxe/Udp4Dxe.inf + NetworkPkg/Udp6Dxe/Udp6Dxe.inf + NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf + + MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf + MsvmPkg/AcpiTables/AcpiTables.inf + MsvmPkg/AziHsmDxe/AziHsmDxe.inf + MsvmPkg/EfiHvDxe/EfiHvDxe.inf + MsvmPkg/EmclDxe/EmclDxe.inf + MsvmPkg/EventLogDxe/EventLogDxe.inf + MsvmPkg/MsvmPcAtRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf + MsvmPkg/NetvscDxe/NetvscDxe.inf + MsvmPkg/EfiDiagnosticsDxe/EfiDiagnosticsDxe.inf + MsvmPkg/IoMmuDxe/IoMmuDxe.inf + MsvmPkg/PlatformDeviceStateHelper/PlatformDeviceStateHelper.inf + MsvmPkg/SerialDxe/SerialDxe.inf + MsvmPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf + MsvmPkg/StorvscDxe/StorvscDxe.inf + MsvmPkg/SynthKeyDxe/SynthKeyDxe.inf + MsvmPkg/SynicTimerDxe/SynicTimerDxe.inf + MsvmPkg/VariableDxe/VariableDxe.inf + MsvmPkg/VideoDxe/VideoDxe.inf + MsvmPkg/VmbfsDxe/VmbfsDxe.inf + MsvmPkg/VmbusDxe/VmbusDxe.inf + MsvmPkg/VmMeasurementDxe/VmMeasurementDxe.inf + MsvmPkg/VpcivscDxe/VpcivscDxe.inf + MsvmPkg/WatchdogTimerDxe/WatchdogTimerDxe.inf + + # Advanced logger components +!if $(FILE_LOGGER) == 1 + AdvLoggerPkg/AdvancedFileLogger/AdvancedFileLogger.inf +!endif + + SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf { + + RngLib|MsvmPkg/Library/MsvmRngLib/MsvmRngLib.inf + } + + # TPM related components + + SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf + + SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf { + + Tpm2DeviceLib|MsvmPkg/Library/Tpm2DeviceLib/Tpm2DeviceLib.inf HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf - NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf - NULL|MsvmPkg/Library/Tcg2PreInitLib/Tcg2PreInitLibDxe.inf - } - - SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf { - - Tpm2DeviceLib|MsvmPkg/Library/Tpm2DeviceLib/Tpm2DeviceLib.inf - HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf - NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf - NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf - NULL|MsvmPkg/Library/Tcg2PreInitLib/Tcg2PreInitLibPei.inf - } - - MsvmPkg/MsvmTcg2PlatformDxe/MsvmTcg2PlatformDxe.inf { - - Tpm2DeviceLib|MsvmPkg/Library/Tpm2DeviceLib/Tpm2DeviceLib.inf - TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf - NULL|MsvmPkg/Library/Tcg2PreInitLib/Tcg2PreInitLibDxe.inf - } - -!if $(LEGACY_DEBUGGER) == 1 - MsKdDebugPkg2/KdDxe/KdDxe.inf { - - PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf - SerialPortLib|MsvmPkg/Library/KdPL011SerialPortLib/KdPL011SerialPortLib.inf - SourceDebugEnabledLib|MsvmPkg/Library/SourceDebugEnabled/SourceDebugEnabledLib.inf - } -!endif - - # UI Theme Protocol - MsGraphicsPkg/MsUiTheme/Dxe/MsUiThemeProtocol.inf - - # Simple Window Manager (SWM) driver. - MsGraphicsPkg/SimpleWindowManagerDxe/SimpleWindowManagerDxe.inf - - # Rendering Engine (SRE) driver. - MsGraphicsPkg/RenderingEngineDxe/RenderingEngineDxe.inf - - # FrontPage application. - MsvmPkg/FrontPage/FrontPage.inf - - MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf { - - LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf - } - -!if $(PRM_ENABLE) == TRUE - # - # PRM Configuration Driver - # - PrmPkg/PrmConfigDxe/PrmConfigDxe.inf { - - NULL|PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf - NULL|PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf - } - - # - # PRM Module Loader Driver - # - PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf - - # - # PRM SSDT Installation Driver - # - PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf - - # - # PRM Sample Modules - # - PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf - PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf -!endif - + NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf + NULL|MsvmPkg/Library/Tcg2PreInitLib/Tcg2PreInitLibDxe.inf + } + + SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf { + + Tpm2DeviceLib|MsvmPkg/Library/Tpm2DeviceLib/Tpm2DeviceLib.inf + HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf + NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf + NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf + NULL|MsvmPkg/Library/Tcg2PreInitLib/Tcg2PreInitLibPei.inf + } + + MsvmPkg/MsvmTcg2PlatformDxe/MsvmTcg2PlatformDxe.inf { + + Tpm2DeviceLib|MsvmPkg/Library/Tpm2DeviceLib/Tpm2DeviceLib.inf + TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf + NULL|MsvmPkg/Library/Tcg2PreInitLib/Tcg2PreInitLibDxe.inf + } + +!if $(LEGACY_DEBUGGER) == 1 + MsKdDebugPkg2/KdDxe/KdDxe.inf { + + PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf + SerialPortLib|MsvmPkg/Library/KdPL011SerialPortLib/KdPL011SerialPortLib.inf + SourceDebugEnabledLib|MsvmPkg/Library/SourceDebugEnabled/SourceDebugEnabledLib.inf + } +!endif + + # UI Theme Protocol + MsGraphicsPkg/MsUiTheme/Dxe/MsUiThemeProtocol.inf + + # Simple Window Manager (SWM) driver. + MsGraphicsPkg/SimpleWindowManagerDxe/SimpleWindowManagerDxe.inf + + # Rendering Engine (SRE) driver. + MsGraphicsPkg/RenderingEngineDxe/RenderingEngineDxe.inf + + # FrontPage application. + MsvmPkg/FrontPage/FrontPage.inf + + MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf { + + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf + } + +!if $(PRM_ENABLE) == TRUE + # + # PRM Configuration Driver + # + PrmPkg/PrmConfigDxe/PrmConfigDxe.inf { + + NULL|PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf + NULL|PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf + } + + # + # PRM Module Loader Driver + # + PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf + + # + # PRM SSDT Installation Driver + # + PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf + + # + # PRM Sample Modules + # + PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf + PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf +!endif + # TODO: There should be only one [BuildOptions]. -[BuildOptions] - # Generate PDBs on release builds with full debugging, with linker and CC flags +[BuildOptions] + # Generate PDBs on release builds with full debugging, with linker and CC flags MSFT:*_*_*_DLINK_FLAGS = /DEBUG:FULL /PDBALTPATH:$(MODULE_NAME).pdb *_CLANGPDB_*_DLINK_FLAGS = /DEBUG:FULL /PDBALTPATH:$(MODULE_NAME).pdb - # /d2overrideInterlockedIntrinsArm64- inlines Interlocked sequences. - # TODO: And they are ARMv8.0 that ARMcorp says not to use on newer hardware. + # /d2overrideInterlockedIntrinsArm64- inlines Interlocked sequences. + # TODO: And they are ARMv8.0 that ARMcorp says not to use on newer hardware. MSFT:*_*_*_CC_FLAGS = /Z7 /d2overrideInterlockedIntrinsArm64- *_CLANGPDB_*_CC_FLAGS = -g -gcodeview -gcodeview-ghash -gcodeview-command-line *_GCC_*_ASLDLINK_FLAGS = -z common-page-size=0x1000 *_GCC_*_DLINK_FLAGS = -z common-page-size=0x1000 - - # Set file alignment and (memory) alignment to 4K. - # Memory alignment 4K is required for page protection. - # i.e. So that, text/data/rdata are on different pages, - # so that data/rdata are not executable and text/rdata are not writable. - # This is the main reason sections exist and the main feature of the PE format. - # File==memory for execute in place, or loader perf/simplicity otherwise. - # Memory alignment defaults to 4K, if not otherwise changed by build system. + + # Set file alignment and (memory) alignment to 4K. + # Memory alignment 4K is required for page protection. + # i.e. So that, text/data/rdata are on different pages, + # so that data/rdata are not executable and text/rdata are not writable. + # This is the main reason sections exist and the main feature of the PE format. + # File==memory for execute in place, or loader perf/simplicity otherwise. + # Memory alignment defaults to 4K, if not otherwise changed by build system. MSFT:*_*_*_DLINK_FLAGS = -align:4096 -filealign:4096 *_CLANGPDB_*_DLINK_FLAGS = -align:4096 -filealign:4096 diff --git a/MsvmPkg/MsvmPkgAARCH64.fdf b/MsvmPkg/MsvmPkgAARCH64.fdf index 499ef7d784..9a5d459b51 100644 --- a/MsvmPkg/MsvmPkgAARCH64.fdf +++ b/MsvmPkg/MsvmPkgAARCH64.fdf @@ -1,400 +1,403 @@ -## @file -# Microsoft ARM64 Virtual Machine Firmware Flash Description File -# -# Copyright (C) Microsoft. -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -# This file decribes the layout and contents of the firmware image that -# would normally get burned to flash on a physical machine. In a Hyper-V VM -# this image gets put into VM memory by the host VM worker process. The -# net effect is the same. The code is present in the VM memory space. -# -## - -################################################################################ -# This FD section describes the layout of the firmware image. -# -# FD.MSVM - -# 0x800000 +----------------------------+ -# | | -# | DXE modules | -# | | -# | | -# | DXE Volume | -# 0x200000 +----------------------------+ -# | PEI modules | -# | PEI_Core | -# | SEC | -# | | -# | MAIN Volume | -# 0x1000 +----------------------------+ -# | empty page | -# 0x0 +----------------------------+ -# -[FD.MSVM] -BaseAddress = 0x00000000|gMsvmPkgTokenSpaceGuid.PcdFdBaseAddress +## @file +# Microsoft ARM64 Virtual Machine Firmware Flash Description File +# +# Copyright (C) Microsoft. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# This file decribes the layout and contents of the firmware image that +# would normally get burned to flash on a physical machine. In a Hyper-V VM +# this image gets put into VM memory by the host VM worker process. The +# net effect is the same. The code is present in the VM memory space. +# +## + +################################################################################ +# This FD section describes the layout of the firmware image. +# +# FD.MSVM + +# 0x800000 +----------------------------+ +# | | +# | DXE modules | +# | | +# | | +# | DXE Volume | +# 0x200000 +----------------------------+ +# | PEI modules | +# | PEI_Core | +# | SEC | +# | | +# | MAIN Volume | +# 0x1000 +----------------------------+ +# | empty page | +# 0x0 +----------------------------+ +# +[FD.MSVM] +BaseAddress = 0x00000000|gMsvmPkgTokenSpaceGuid.PcdFdBaseAddress !if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG -Size = 0x00810000|gMsvmPkgTokenSpaceGuid.PcdFdSize +Size = 0x00810000|gMsvmPkgTokenSpaceGuid.PcdFdSize !else Size = 0x00800000|gMsvmPkgTokenSpaceGuid.PcdFdSize !endif - -ErasePolarity = 1 -BlockSize = 0x1000 # This multiplied by NumBlocks should == Size + +ErasePolarity = 1 +BlockSize = 0x1000 # This multiplied by NumBlocks should == Size !if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG -NumBlocks = 0x810 +NumBlocks = 0x810 !else NumBlocks = 0x800 !endif - -# -# UEFI has trouble dealing with FVs that reside at physical address 0x0. -# Therefore this dummy 4K page is put at offset zero. An instruction is -# put at the beginning to jump to the beginning of the first FV so the -# processor can start either at the beginning of the image or at the -# beginning of the first FV. -# -0x00000000|0x00001000 -DATA = { - 0x00, 0x04, 0x00, 0x14 # 'b 0x1000' AArch64 instruction -} - -# MAIN volume (start|size) -0x00001000|0x001FF000 -gMsvmPkgTokenSpaceGuid.PcdFvBaseAddress|gMsvmPkgTokenSpaceGuid.PcdFvSize -FV = MAIN - -# DXE volume that is not force rebased so that the section alignment and -# file alignment do not need to match + +# +# UEFI has trouble dealing with FVs that reside at physical address 0x0. +# Therefore this dummy 4K page is put at offset zero. An instruction is +# put at the beginning to jump to the beginning of the first FV so the +# processor can start either at the beginning of the image or at the +# beginning of the first FV. +# +0x00000000|0x00001000 +DATA = { + 0x00, 0x04, 0x00, 0x14 # 'b 0x1000' AArch64 instruction +} + +# MAIN volume (start|size) +0x00001000|0x001FF000 +gMsvmPkgTokenSpaceGuid.PcdFvBaseAddress|gMsvmPkgTokenSpaceGuid.PcdFvSize +FV = MAIN + +# DXE volume that is not force rebased so that the section alignment and +# file alignment do not need to match !if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG 0x00200000|0x00610000 !else 0x00200000|0x00600000 -!endif -gMsvmPkgTokenSpaceGuid.PcdDxeFvBaseAddress|gMsvmPkgTokenSpaceGuid.PcdDxeFvSize -FV = DXE - -################################################################################ -# -# This FV section describes the MAIN volume contents. It contains SEC and PEI -# modules. This section gets forced rebased by the basetools, as it contains -# some XIP modules. DxeMain is in this FV also so that DxeIpl can find and -# load it. However, the DXE modules are in a separate FV so that they can -# not be force rebased, as they are non-XIP and the DXE_RUNTIME_DRIVERs -# do not meet the requirement for force rebasing (that they have section -# alignment and file alignment equivalent). There is an added benefit here -# that PeiCore does not have to spend time enumerating the DXE drivers to -# determine if it needs to launch them or not. -# -[FV.MAIN] -BlockSize = 0x1000 -FvAlignment = 4K -ERASE_POLARITY = 1 -MEMORY_MAPPED = TRUE -STICKY_WRITE = TRUE -LOCK_CAP = TRUE -LOCK_STATUS = TRUE -WRITE_DISABLED_CAP = TRUE -WRITE_ENABLED_CAP = TRUE -WRITE_STATUS = TRUE -WRITE_LOCK_CAP = TRUE -WRITE_LOCK_STATUS = TRUE -READ_DISABLED_CAP = TRUE -READ_ENABLED_CAP = TRUE -READ_STATUS = TRUE -READ_LOCK_CAP = TRUE -READ_LOCK_STATUS = TRUE - -# -# Dispatch these components first in PEI -# -APRIORI PEI { - INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf -} - -# -# SEC and PEI components -# -INF MsvmPkg/Sec/SecMain.inf -INF ArmPkg/Drivers/CpuPei/CpuPei.inf -INF DebuggerFeaturePkg/DebugConfigPei/DebugConfigPei.inf -INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf -INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf -INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf -INF MdeModulePkg/Core/Pei/PeiMain.inf -INF MsGraphicsPkg/MsUiTheme/Pei/MsUiThemePpi.inf -INF MsvmPkg/PlatformPei/PlatformPei.inf -INF SecurityPkg/RandomNumberGenerator/RngPei/RngPei.inf -INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf - -!include $(SHARED_CRYPTO_PATH)/Driver/Bin/CryptoDriver.PEI.inc.fdf - -# -# DXE Components -# -INF MdeModulePkg/Core/Dxe/DxeMain.inf - -[FV.DXE] -BlockSize = 0x1000 -FvAlignment = 4K -FvForceRebase = FALSE -ERASE_POLARITY = 1 -MEMORY_MAPPED = TRUE -STICKY_WRITE = TRUE -LOCK_CAP = TRUE -LOCK_STATUS = TRUE -WRITE_DISABLED_CAP = TRUE -WRITE_ENABLED_CAP = TRUE -WRITE_STATUS = TRUE -WRITE_LOCK_CAP = TRUE -WRITE_LOCK_STATUS = TRUE -READ_DISABLED_CAP = TRUE -READ_ENABLED_CAP = TRUE -READ_STATUS = TRUE -READ_LOCK_CAP = TRUE -READ_LOCK_STATUS = TRUE - -# -# Dispatch these components first in DXE -# -APRIORI DXE { - INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf - INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf - INF ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf - INF MsvmPkg/EfiHvDxe/EfiHvDxe.inf - INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf - INF MsvmPkg/EventLogDxe/EventLogDxe.inf - INF MsvmPkg/SynicTimerDxe/SynicTimerDxe.inf - INF MsvmPkg/VariableDxe/VariableDxe.inf +!endif +gMsvmPkgTokenSpaceGuid.PcdDxeFvBaseAddress|gMsvmPkgTokenSpaceGuid.PcdDxeFvSize +FV = DXE + +################################################################################ +# +# This FV section describes the MAIN volume contents. It contains SEC and PEI +# modules. This section gets forced rebased by the basetools, as it contains +# some XIP modules. DxeMain is in this FV also so that DxeIpl can find and +# load it. However, the DXE modules are in a separate FV so that they can +# not be force rebased, as they are non-XIP and the DXE_RUNTIME_DRIVERs +# do not meet the requirement for force rebasing (that they have section +# alignment and file alignment equivalent). There is an added benefit here +# that PeiCore does not have to spend time enumerating the DXE drivers to +# determine if it needs to launch them or not. +# +[FV.MAIN] +BlockSize = 0x1000 +FvAlignment = 4K +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + +# +# Dispatch these components first in PEI +# +APRIORI PEI { + INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf +} + +# +# SEC and PEI components +# +INF MsvmPkg/Sec/SecMain.inf +INF ArmPkg/Drivers/CpuPei/CpuPei.inf +INF DebuggerFeaturePkg/DebugConfigPei/DebugConfigPei.inf +INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf +INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf +INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +INF MdeModulePkg/Core/Pei/PeiMain.inf +INF MsGraphicsPkg/MsUiTheme/Pei/MsUiThemePpi.inf +INF MsvmPkg/PlatformPei/PlatformPei.inf +INF SecurityPkg/RandomNumberGenerator/RngPei/RngPei.inf +INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf + +!include $(SHARED_CRYPTO_PATH)/Driver/Bin/CryptoDriver.PEI.inc.fdf + +# +# DXE Components +# +INF MdeModulePkg/Core/Dxe/DxeMain.inf + +[FV.DXE] +BlockSize = 0x1000 +FvAlignment = 4K +FvForceRebase = FALSE +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + +# +# Dispatch these components first in DXE +# +APRIORI DXE { + INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf + INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf + INF ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf + INF MsvmPkg/EfiHvDxe/EfiHvDxe.inf + INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf + INF MsvmPkg/EventLogDxe/EventLogDxe.inf + INF MsvmPkg/SynicTimerDxe/SynicTimerDxe.inf + INF MsvmPkg/VariableDxe/VariableDxe.inf INF MsvmPkg/EfiDiagnosticsDxe/EfiDiagnosticsDxe.inf - INF MsvmPkg/PlatformDeviceStateHelper/PlatformDeviceStateHelper.inf -} - -INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf -INF ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf - -!if $(FILE_LOGGER) == 1 - INF AdvLoggerPkg/AdvancedFileLogger/AdvancedFileLogger.inf -!endif - -INF FatPkg/EnhancedFatDxe/Fat.inf - -INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf -INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf -INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf -INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf -INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf -INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf -INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf -INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf -INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf -INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf -INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf -INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf -INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf -INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf -INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf -INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf -INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf -INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf -INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf -INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf -INF MdeModulePkg/Universal/Metronome/Metronome.inf -INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf -INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf -INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf -INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf -INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf -INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf -INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf - -INF MsGraphicsPkg/DisplayEngineDxe/DisplayEngineDxe.inf - -!include $(SHARED_CRYPTO_PATH)/Driver/Bin/CryptoDriver.DXE.inc.fdf - -INF MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf -INF RuleOverride=ACPITABLE MsvmPkg/AcpiTables/AcpiTables.inf -INF MsvmPkg/AziHsmDxe/AziHsmDxe.inf -INF MsvmPkg/EfiHvDxe/EfiHvDxe.inf -INF MsvmPkg/EmclDxe/EmclDxe.inf -INF MsvmPkg/EventLogDxe/EventLogDxe.inf -INF MsvmPkg/MsvmPcAtRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf -INF MsvmPkg/NetvscDxe/NetvscDxe.inf -INF MsvmPkg/NvmExpressDxe/NvmExpressDxe.inf + INF MsvmPkg/PlatformDeviceStateHelper/PlatformDeviceStateHelper.inf +} + +INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf +INF ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf + +!if $(FILE_LOGGER) == 1 + INF AdvLoggerPkg/AdvancedFileLogger/AdvancedFileLogger.inf +!endif + +INF FatPkg/EnhancedFatDxe/Fat.inf + +INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf +INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf +INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf +INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf +INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf +INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf +INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf +INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf +INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf +INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf +INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf +INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf +INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf +INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf +INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf +INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf +INF MdeModulePkg/Universal/Metronome/Metronome.inf +INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf +INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf +INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf +INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf +INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf +INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + +INF MsGraphicsPkg/DisplayEngineDxe/DisplayEngineDxe.inf + +!include $(SHARED_CRYPTO_PATH)/Driver/Bin/CryptoDriver.DXE.inc.fdf + +INF MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf +INF RuleOverride=ACPITABLE MsvmPkg/AcpiTables/AcpiTables.inf +INF MsvmPkg/AziHsmDxe/AziHsmDxe.inf +INF MsvmPkg/EfiHvDxe/EfiHvDxe.inf +INF MsvmPkg/EmclDxe/EmclDxe.inf +INF MsvmPkg/EventLogDxe/EventLogDxe.inf +INF MsvmPkg/MsvmPcAtRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf +INF MsvmPkg/NetvscDxe/NetvscDxe.inf INF MsvmPkg/EfiDiagnosticsDxe/EfiDiagnosticsDxe.inf -INF MsvmPkg/PlatformDeviceStateHelper/PlatformDeviceStateHelper.inf -INF MsvmPkg/SerialDxe/SerialDxe.inf -INF MsvmPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf -INF MsvmPkg/StorvscDxe/StorvscDxe.inf -INF MsvmPkg/SynicTimerDxe/SynicTimerDxe.inf -INF MsvmPkg/SynthKeyDxe/SynthKeyDxe.inf -INF MsvmPkg/VariableDxe/VariableDxe.inf -INF MsvmPkg/VideoDxe/VideoDxe.inf -INF MsvmPkg/VmbfsDxe/VmbfsDxe.inf -INF MsvmPkg/VmbusDxe/VmbusDxe.inf -INF MsvmPkg/VmMeasurementDxe/VmMeasurementDxe.inf -INF MsvmPkg/VpcivscDxe/VpcivscDxe.inf -INF MsvmPkg/WatchdogTimerDxe/WatchdogTimerDxe.inf - -!if $(PRM_ENABLE) == TRUE -INF PrmPkg/PrmConfigDxe/PrmConfigDxe.inf -INF PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf -INF PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf -INF PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf -INF PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf -!endif - -INF NetworkPkg/ArpDxe/ArpDxe.inf -INF NetworkPkg/Dhcp4Dxe/Dhcp4Dxe.inf -INF NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf -INF NetworkPkg/DnsDxe/DnsDxe.inf -INF NetworkPkg/DpcDxe/DpcDxe.inf -INF NetworkPkg/HttpDxe/HttpDxe.inf -INF NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf -INF NetworkPkg/Ip4Dxe/Ip4Dxe.inf -INF NetworkPkg/Ip6Dxe/Ip6Dxe.inf -INF NetworkPkg/MnpDxe/MnpDxe.inf -INF NetworkPkg/Mtftp4Dxe/Mtftp4Dxe.inf -INF NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf -INF NetworkPkg/TcpDxe/TcpDxe.inf -INF NetworkPkg/TlsDxe/TlsDxe.inf -INF NetworkPkg/Udp4Dxe/Udp4Dxe.inf -INF NetworkPkg/Udp6Dxe/Udp6Dxe.inf -INF NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf - -INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf -INF SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf -INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf -INF MsvmPkg/MsvmTcg2PlatformDxe/MsvmTcg2PlatformDxe.inf - -# UI Theme Protocol. -INF MsGraphicsPkg/MsUiTheme/Dxe/MsUiThemeProtocol.inf -# Rendering Engine (SRE) driver. -INF MsGraphicsPkg/RenderingEngineDxe/RenderingEngineDxe.inf -# Simple Window Manager (SWM) driver. -INF MsGraphicsPkg/SimpleWindowManagerDxe/SimpleWindowManagerDxe.inf - -# FrontPage application. -INF MsvmPkg/FrontPage/FrontPage.inf - -#INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf - -FILE FREEFORM = PCD(gMsvmPkgTokenSpaceGuid.PcdLogoFile) { - SECTION RAW = MsvmPkg/FrontPage/Resources/BootLogo.bmp - SECTION UI = "Logo" - } - -FILE FREEFORM = PCD(gMsvmPkgTokenSpaceGuid.PcdFrontPageLogoFile) { - SECTION RAW = MsvmPkg/FrontPage/Resources/FrontpageLogo.bmp -} - -FILE FREEFORM = PCD(gMsvmPkgTokenSpaceGuid.PcdBootFailIndicatorFile) { - SECTION RAW = MsvmPkg/FrontPage/Resources/NoBoot.bmp -} - -################################################################################ -# Rules section. -[Rule.Common.SEC] - FILE SEC = $(NAMED_GUID) { - PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING ="$(MODULE_NAME)" Optional - VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.PEI_CORE] - FILE PEI_CORE = $(NAMED_GUID) { - PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING ="$(MODULE_NAME)" Optional - VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.PEIM] - FILE PEIM = $(NAMED_GUID) { - PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.PEIM.BINARY] - FILE PEIM = $(NAMED_GUID) { - PEI_DEPEX PEI_DEPEX Optional |.depex - PE32 PE32 Align = Auto |.efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.DXE_CORE] - FILE DXE_CORE = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.DXE_DRIVER] - FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - RAW ACPI Optional |.acpi - RAW ASL Optional |.aml - } - -[Rule.Common.DXE_DRIVER.BINARY] - FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional |.depex - PE32 PE32 |.efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.DXE_RUNTIME_DRIVER] - FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.UEFI_DRIVER] - FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.UEFI_DRIVER.BINARY] - FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional |.depex - PE32 PE32 |.efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.UEFI_APPLICATION] - FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.UEFI_APPLICATION.BINARY] - FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 |.efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - } - -[Rule.Common.USER_DEFINED.ACPITABLE] - FILE FREEFORM = $(NAMED_GUID) { - RAW ACPI |.acpi - RAW ASL |.aml - } - -[Rule.Common.USER_DEFINED.CSM] - FILE FREEFORM = $(NAMED_GUID) { - RAW BIN |.bin - } +INF MsvmPkg/IoMmuDxe/IoMmuDxe.inf +INF MsvmPkg/PlatformDeviceStateHelper/PlatformDeviceStateHelper.inf +INF MsvmPkg/SerialDxe/SerialDxe.inf +INF MsvmPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf +INF MsvmPkg/StorvscDxe/StorvscDxe.inf +INF MsvmPkg/SynicTimerDxe/SynicTimerDxe.inf +INF MsvmPkg/SynthKeyDxe/SynthKeyDxe.inf +INF MsvmPkg/VariableDxe/VariableDxe.inf +INF MsvmPkg/VideoDxe/VideoDxe.inf +INF MsvmPkg/VmbfsDxe/VmbfsDxe.inf +INF MsvmPkg/VmbusDxe/VmbusDxe.inf +INF MsvmPkg/VmMeasurementDxe/VmMeasurementDxe.inf +INF MsvmPkg/VpcivscDxe/VpcivscDxe.inf +INF MsvmPkg/WatchdogTimerDxe/WatchdogTimerDxe.inf + +!if $(PRM_ENABLE) == TRUE +INF PrmPkg/PrmConfigDxe/PrmConfigDxe.inf +INF PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf +INF PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf +INF PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf +INF PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf +!endif + +INF SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.inf + +INF NetworkPkg/ArpDxe/ArpDxe.inf +INF NetworkPkg/Dhcp4Dxe/Dhcp4Dxe.inf +INF NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf +INF NetworkPkg/DnsDxe/DnsDxe.inf +INF NetworkPkg/DpcDxe/DpcDxe.inf +INF NetworkPkg/HttpDxe/HttpDxe.inf +INF NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf +INF NetworkPkg/Ip4Dxe/Ip4Dxe.inf +INF NetworkPkg/Ip6Dxe/Ip6Dxe.inf +INF NetworkPkg/MnpDxe/MnpDxe.inf +INF NetworkPkg/Mtftp4Dxe/Mtftp4Dxe.inf +INF NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf +INF NetworkPkg/TcpDxe/TcpDxe.inf +INF NetworkPkg/TlsDxe/TlsDxe.inf +INF NetworkPkg/Udp4Dxe/Udp4Dxe.inf +INF NetworkPkg/Udp6Dxe/Udp6Dxe.inf +INF NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf + +INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf +INF SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf +INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf +INF MsvmPkg/MsvmTcg2PlatformDxe/MsvmTcg2PlatformDxe.inf + +# UI Theme Protocol. +INF MsGraphicsPkg/MsUiTheme/Dxe/MsUiThemeProtocol.inf +# Rendering Engine (SRE) driver. +INF MsGraphicsPkg/RenderingEngineDxe/RenderingEngineDxe.inf +# Simple Window Manager (SWM) driver. +INF MsGraphicsPkg/SimpleWindowManagerDxe/SimpleWindowManagerDxe.inf + +# FrontPage application. +INF MsvmPkg/FrontPage/FrontPage.inf + +#INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf + +FILE FREEFORM = PCD(gMsvmPkgTokenSpaceGuid.PcdLogoFile) { + SECTION RAW = MsvmPkg/FrontPage/Resources/BootLogo.bmp + SECTION UI = "Logo" + } + +FILE FREEFORM = PCD(gMsvmPkgTokenSpaceGuid.PcdFrontPageLogoFile) { + SECTION RAW = MsvmPkg/FrontPage/Resources/FrontpageLogo.bmp +} + +FILE FREEFORM = PCD(gMsvmPkgTokenSpaceGuid.PcdBootFailIndicatorFile) { + SECTION RAW = MsvmPkg/FrontPage/Resources/NoBoot.bmp +} + +################################################################################ +# Rules section. +[Rule.Common.SEC] + FILE SEC = $(NAMED_GUID) { + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING ="$(MODULE_NAME)" Optional + VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.PEI_CORE] + FILE PEI_CORE = $(NAMED_GUID) { + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING ="$(MODULE_NAME)" Optional + VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.PEIM] + FILE PEIM = $(NAMED_GUID) { + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.PEIM.BINARY] + FILE PEIM = $(NAMED_GUID) { + PEI_DEPEX PEI_DEPEX Optional |.depex + PE32 PE32 Align = Auto |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.DXE_CORE] + FILE DXE_CORE = $(NAMED_GUID) { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.DXE_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml + } + +[Rule.Common.DXE_DRIVER.BINARY] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional |.depex + PE32 PE32 |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.DXE_RUNTIME_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.UEFI_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.UEFI_DRIVER.BINARY] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional |.depex + PE32 PE32 |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.UEFI_APPLICATION] + FILE APPLICATION = $(NAMED_GUID) { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.UEFI_APPLICATION.BINARY] + FILE APPLICATION = $(NAMED_GUID) { + PE32 PE32 |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.USER_DEFINED.ACPITABLE] + FILE FREEFORM = $(NAMED_GUID) { + RAW ACPI |.acpi + RAW ASL |.aml + } + +[Rule.Common.USER_DEFINED.CSM] + FILE FREEFORM = $(NAMED_GUID) { + RAW BIN |.bin + } diff --git a/MsvmPkg/MsvmPkgX64.dsc b/MsvmPkg/MsvmPkgX64.dsc index d3e8526ea9..ff9a24e29a 100644 --- a/MsvmPkg/MsvmPkgX64.dsc +++ b/MsvmPkg/MsvmPkgX64.dsc @@ -37,18 +37,18 @@ ################################################################################ [BuildOptions] *_*_*_GENFW_FLAGS = --keepexceptiontable - *_*_*_CC_FLAGS = -D MS_HYP_CHANGE_BEGIN -D MS_HYP_CHANGE -D MS_HYP -D MU_CHANGE - DEBUG_*_*_CC_FLAGS = -D DEBUG_PLATFORM + *_*_*_CC_FLAGS = -D MS_HYP_CHANGE_BEGIN -D MS_HYP_CHANGE -D MS_HYP -D MU_CHANGE + DEBUG_*_*_CC_FLAGS = -D DEBUG_PLATFORM # Generate PDBs on release builds with full debugging, with linker and CC flags MSFT:*_*_*_DLINK_FLAGS = /DEBUG:FULL /PDBALTPATH:$(MODULE_NAME).pdb - *_CLANGPDB_*_DLINK_FLAGS = /DEBUG:FULL /PDBALTPATH:$(MODULE_NAME).pdb + *_CLANGPDB_*_DLINK_FLAGS = /DEBUG:FULL /PDBALTPATH:$(MODULE_NAME).pdb MSFT:*_*_*_CC_FLAGS = /Z7 - *_CLANGPDB_*_CC_FLAGS = -g -gcodeview -gcodeview-ghash -gcodeview-command-line - - *_GCC_*_ASLDLINK_FLAGS = -z common-page-size=0x1000 - *_GCC_*_DLINK_FLAGS = -z common-page-size=0x1000 - *_CLANGPDB_X64_DLINK_FLAGS = -align:4096 + *_CLANGPDB_*_CC_FLAGS = -g -gcodeview -gcodeview-ghash -gcodeview-command-line + + *_GCC_*_ASLDLINK_FLAGS = -z common-page-size=0x1000 + *_GCC_*_DLINK_FLAGS = -z common-page-size=0x1000 + *_CLANGPDB_X64_DLINK_FLAGS = -align:4096 # Set file alignment and (memory) alignment to 4K. # Memory alignment 4K is required for page protection. @@ -59,12 +59,12 @@ # The linker defaults to -align:4096, but this could be preceded by a lower -align specified # elsewhere in EFI build system. [BuildOptions.common.EDKII.DXE_CORE] - MSFT:*_*_*_DLINK_FLAGS = -align:4096 -filealign:4096 - *_CLANGPDB_*_DLINK_FLAGS = -align:4096 -filealign:4096 + MSFT:*_*_*_DLINK_FLAGS = -align:4096 -filealign:4096 + *_CLANGPDB_*_DLINK_FLAGS = -align:4096 -filealign:4096 [BuildOptions.common.EDKII.SEC, BuildOptions.common.EDKII.PEIM, BuildOptions.common.EDKII.PEI_CORE] - MSFT:*_*_*_DLINK_FLAGS = -align:4096 -filealign:4096 - *_CLANGPDB_*_DLINK_FLAGS = -align:4096 -filealign:4096 + MSFT:*_*_*_DLINK_FLAGS = -align:4096 -filealign:4096 + *_CLANGPDB_*_DLINK_FLAGS = -align:4096 -filealign:4096 ################################################################################ # @@ -258,6 +258,7 @@ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf HttpLib|NetworkPkg/Library/DxeHttpLib/DxeHttpLib.inf + IoMmuLib|MdeModulePkg/Library/IoMmuLib/IoMmuLib.inf IpIoLib|NetworkPkg/Library/DxeIpIoLib/DxeIpIoLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf @@ -278,7 +279,6 @@ WatchdogTimerLib|MsvmPkg/Library/WatchdogTimerLib/WatchdogTimerLib.inf PciSegmentLib|MdePkg/Library/PciSegmentLibSegmentInfo/BasePciSegmentLibSegmentInfo.inf PciSegmentInfoLib|MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.inf - IoMmuLib|MdeModulePkg/Library/IoMmuLibNull/IoMmuLibNull.inf # # Library instances overrides for just DXE CORE @@ -876,6 +876,7 @@ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf + MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf @@ -916,8 +917,8 @@ MsvmPkg/AziHsmDxe/AziHsmDxe.inf MsvmPkg/MsvmPcAtRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf MsvmPkg/NetvscDxe/NetvscDxe.inf - MsvmPkg/NvmExpressDxe/NvmExpressDxe.inf MsvmPkg/EfiDiagnosticsDxe/EfiDiagnosticsDxe.inf + MsvmPkg/IoMmuDxe/IoMmuDxe.inf MsvmPkg/PlatformDeviceStateHelper/PlatformDeviceStateHelper.inf MsvmPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf MsvmPkg/StorvscDxe/StorvscDxe.inf @@ -964,8 +965,8 @@ NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf NULL|MsvmPkg/Library/Tcg2PreInitLib/Tcg2PreInitLibPei.inf - #special library For HyperV so that boot doesn't measure FVs - NULL|MsvmPkg/Library/ExcludeFvsFromMeasurementLib/ExcludeFvsFromMeasurementLib.inf + #special library For HyperV so that boot doesn't measure FVs + NULL|MsvmPkg/Library/ExcludeFvsFromMeasurementLib/ExcludeFvsFromMeasurementLib.inf } MsvmPkg/MsvmTcg2PlatformDxe/MsvmTcg2PlatformDxe.inf { diff --git a/MsvmPkg/MsvmPkgX64.fdf b/MsvmPkg/MsvmPkgX64.fdf index fe965e652a..00ff3c96b8 100644 --- a/MsvmPkg/MsvmPkgX64.fdf +++ b/MsvmPkg/MsvmPkgX64.fdf @@ -46,45 +46,45 @@ # [FD.MSVM] -BaseAddress = 0x00100000|gMsvmPkgTokenSpaceGuid.PcdFdBaseAddress -!if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG -Size = 0x00800000|gMsvmPkgTokenSpaceGuid.PcdFdSize -!else -Size = 0x00600000|gMsvmPkgTokenSpaceGuid.PcdFdSize -!endif +BaseAddress = 0x00100000|gMsvmPkgTokenSpaceGuid.PcdFdBaseAddress +!if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG +Size = 0x00800000|gMsvmPkgTokenSpaceGuid.PcdFdSize +!else +Size = 0x00600000|gMsvmPkgTokenSpaceGuid.PcdFdSize +!endif ErasePolarity = 1 BlockSize = 0x1000 -!if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG -NumBlocks = 0x800 -!else -NumBlocks = 0x600 -!endif +!if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG +NumBlocks = 0x800 +!else +NumBlocks = 0x600 +!endif # DXE volume that is not force rebased so that the section alignment and # file alignment do not need to match -!if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG -0x00000000|0x00500000 -!else -0x00000000|0x004E0000 -!endif +!if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG +0x00000000|0x00500000 +!else +0x00000000|0x004E0000 +!endif gMsvmPkgTokenSpaceGuid.PcdDxeFvBaseAddress|gMsvmPkgTokenSpaceGuid.PcdDxeFvSize FV = DXE # The MAIN volume (start|size) -!if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG -0x00500000|0x100000 -!else -0x004E0000|0x100000 +!if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG +0x00500000|0x100000 +!else +0x004E0000|0x100000 !endif gMsvmPkgTokenSpaceGuid.PcdFvBaseAddress|gMsvmPkgTokenSpaceGuid.PcdFvSize FV = MAINFV # The SEC volume (start|size) -!if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG -0x00600000|0x00020000 -!else -0x005E0000|0x00020000 +!if $(TOOL_CHAIN_TAG) == GCC and $(TARGET) == DEBUG +0x00600000|0x00020000 +!else +0x005E0000|0x00020000 !endif FV = SECFV @@ -93,7 +93,7 @@ FV = SECFV # This FV section describes the SEC volume contents. # [FV.SECFV] -BlockSize = 0x1000 +BlockSize = 0x1000 FvAlignment = 16 ERASE_POLARITY = 1 MEMORY_MAPPED = TRUE @@ -212,7 +212,7 @@ APRIORI DXE { INF MsvmPkg/EventLogDxe/EventLogDxe.inf INF MsvmPkg/SynicTimerDxe/SynicTimerDxe.inf INF MsvmPkg/VariableDxe/VariableDxe.inf - INF MsvmPkg/EfiDiagnosticsDxe/EfiDiagnosticsDxe.inf + INF MsvmPkg/EfiDiagnosticsDxe/EfiDiagnosticsDxe.inf INF MsvmPkg/PlatformDeviceStateHelper/PlatformDeviceStateHelper.inf } @@ -223,6 +223,7 @@ APRIORI DXE { INF FatPkg/EnhancedFatDxe/Fat.inf +INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf @@ -266,8 +267,8 @@ INF MsvmPkg/EmclDxe/EmclDxe.inf INF MsvmPkg/EventLogDxe/EventLogDxe.inf INF MsvmPkg/MsvmPcAtRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf INF MsvmPkg/NetvscDxe/NetvscDxe.inf -INF MsvmPkg/NvmExpressDxe/NvmExpressDxe.inf -INF MsvmPkg/EfiDiagnosticsDxe/EfiDiagnosticsDxe.inf +INF MsvmPkg/EfiDiagnosticsDxe/EfiDiagnosticsDxe.inf +INF MsvmPkg/IoMmuDxe/IoMmuDxe.inf INF MsvmPkg/PlatformDeviceStateHelper/PlatformDeviceStateHelper.inf INF MsvmPkg/SerialDxe/SerialDxe.inf INF MsvmPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf diff --git a/MsvmPkg/NvmExpressDxe/ComponentName.c b/MsvmPkg/NvmExpressDxe/ComponentName.c deleted file mode 100644 index a58646b433..0000000000 --- a/MsvmPkg/NvmExpressDxe/ComponentName.c +++ /dev/null @@ -1,228 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - Copyright (c) 2013, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "NvmExpress.h" - -// -// EFI Component Name Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gNvmExpressComponentName = { - NvmExpressComponentNameGetDriverName, - NvmExpressComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gNvmExpressComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)NvmExpressComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)NvmExpressComponentNameGetControllerName, - "en" -}; - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mNvmExpressDriverNameTable[] = { - { "eng;en", L"NVM Express Driver" }, - { NULL, NULL } -}; - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mNvmExpressControllerNameTable[] = { - { "eng;en", L"NVM Express Controller" }, - { NULL, NULL } -}; - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -NvmExpressComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mNvmExpressDriverNameTable, - DriverName, - (BOOLEAN)(This == &gNvmExpressComponentName) - ); -} - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -NvmExpressComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - - // - // Make sure this driver is currently managing ControllHandle - // - Status = EfiTestManagedDevice ( - ControllerHandle, - gNvmExpressDriverBinding.DriverBindingHandle, - &gEfiPciIoProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - ControllerNameTable = mNvmExpressControllerNameTable; - if (ChildHandle != NULL) { - Status = EfiTestChildHandle ( - ControllerHandle, - ChildHandle, - &gEfiNvmExpressPassThruProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the child context - // - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiBlockIoProtocolGuid, - (VOID **)&BlockIo, - gNvmExpressDriverBinding.DriverBindingHandle, - ChildHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (BlockIo); - ControllerNameTable = Device->ControllerNameTable; - } - - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - ControllerNameTable, - ControllerName, - (BOOLEAN)(This == &gNvmExpressComponentName) - ); -} diff --git a/MsvmPkg/NvmExpressDxe/NvmExpress.c b/MsvmPkg/NvmExpressDxe/NvmExpress.c deleted file mode 100644 index 93f9585242..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpress.c +++ /dev/null @@ -1,1817 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
- Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "NvmExpress.h" -#include "NvmExpressBounce.h" // MS_HYP_CHANGE - -// -// NVM Express Driver Binding Protocol Instance -// -EFI_DRIVER_BINDING_PROTOCOL gNvmExpressDriverBinding = { - NvmExpressDriverBindingSupported, - NvmExpressDriverBindingStart, - NvmExpressDriverBindingStop, - 0x10, - NULL, - NULL -}; - -// -// NVM Express EFI Driver Supported EFI Version Protocol Instance -// -EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gNvmExpressDriverSupportedEfiVersion = { - sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol structure. - 0 // Version number to be filled at start up. -}; - -// -// Template for NVM Express Pass Thru Mode data structure. -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_NVM_EXPRESS_PASS_THRU_MODE gEfiNvmExpressPassThruMode = { - EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL | - EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL | - EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_NONBLOCKIO | - EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_CMD_SET_NVM, - sizeof (UINTN), - 0x10100 -}; - -/** - Check if the specified Nvm Express device namespace is active, and create child handles - for them with BlockIo and DiskInfo protocol instances. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be - allocated and built. Caller must set the NamespaceId to zero if the - device path node will contain a valid UUID. - - @retval EFI_SUCCESS All the namespaces in the device are successfully enumerated. - @return Others Some error occurs when enumerating the namespaces. - -**/ -EFI_STATUS -EnumerateNvmeDevNamespace ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - UINT32 NamespaceId - ) -{ - NVME_ADMIN_NAMESPACE_DATA *NamespaceData; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_HANDLE DeviceHandle; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - UINT32 Lbads; - UINT32 Flbas; - UINT32 LbaFmtIdx; - UINT8 Sn[21]; - UINT8 Mn[41]; - VOID *DummyInterface; - - NewDevicePathNode = NULL; - DevicePath = NULL; - Device = NULL; - - // - // Allocate a buffer for Identify Namespace data - // - NamespaceData = AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA)); - if (NamespaceData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - ParentDevicePath = Private->ParentDevicePath; - // - // Identify Namespace - // - Status = NvmeIdentifyNamespace ( - Private, - NamespaceId, - (VOID *)NamespaceData - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - // - // Validate Namespace - // - if (NamespaceData->Ncap == 0) { - Status = EFI_DEVICE_ERROR; - } else { - // - // allocate device private data for each discovered namespace - // - Device = AllocateZeroPool (sizeof (NVME_DEVICE_PRIVATE_DATA)); - if (Device == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - - // - // Initialize SSD namespace instance data - // - Device->Signature = NVME_DEVICE_PRIVATE_DATA_SIGNATURE; - Device->NamespaceId = NamespaceId; - Device->NamespaceUuid = NamespaceData->Eui64; - - Device->ControllerHandle = Private->ControllerHandle; - Device->DriverBindingHandle = Private->DriverBindingHandle; - Device->Controller = Private; - - // - // Build BlockIo media structure - // - Device->Media.MediaId = 0; - Device->Media.RemovableMedia = FALSE; - Device->Media.MediaPresent = TRUE; - Device->Media.LogicalPartition = FALSE; - Device->Media.ReadOnly = FALSE; - Device->Media.WriteCaching = FALSE; - Device->Media.IoAlign = Private->PassThruMode.IoAlign; - - Flbas = NamespaceData->Flbas; - LbaFmtIdx = Flbas & 0xF; - - // - // Currently this NVME driver only suport Metadata Size == 0 - // - if (NamespaceData->LbaFormat[LbaFmtIdx].Ms != 0) { - DEBUG (( - DEBUG_ERROR, - "NVME IDENTIFY NAMESPACE [%d] Ms(%d) is not supported.\n", - NamespaceId, - NamespaceData->LbaFormat[LbaFmtIdx].Ms - )); - Status = EFI_UNSUPPORTED; - goto Exit; - } - - Lbads = NamespaceData->LbaFormat[LbaFmtIdx].Lbads; - Device->Media.BlockSize = (UINT32)1 << Lbads; - - Device->Media.LastBlock = NamespaceData->Nsze - 1; - Device->Media.LogicalBlocksPerPhysicalBlock = 1; - Device->Media.LowestAlignedLba = 1; - - // - // Create BlockIo Protocol instance - // - Device->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2; - Device->BlockIo.Media = &Device->Media; - Device->BlockIo.Reset = NvmeBlockIoReset; - Device->BlockIo.ReadBlocks = NvmeBlockIoReadBlocks; - Device->BlockIo.WriteBlocks = NvmeBlockIoWriteBlocks; - Device->BlockIo.FlushBlocks = NvmeBlockIoFlushBlocks; - - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - if (NVME_SUPPORT_BLOCKIO2 (Private)) { - // We have multiple data queues, so we can support the BlockIo2 protocol - - // Create BlockIo2 Protocol instance - Device->BlockIo2.Media = &Device->Media; - Device->BlockIo2.Reset = NvmeBlockIoResetEx; - Device->BlockIo2.ReadBlocksEx = NvmeBlockIoReadBlocksEx; - Device->BlockIo2.WriteBlocksEx = NvmeBlockIoWriteBlocksEx; - Device->BlockIo2.FlushBlocksEx = NvmeBlockIoFlushBlocksEx; - } - - // MU_CHANGE [END] - Request Number of Queues from Controller - - InitializeListHead (&Device->AsyncQueue); - - // - // Create Media Sanitize Protocol instance - // - Device->MediaSanitize.Revision = MEDIA_SANITIZE_PROTOCOL_REVISION; - Device->MediaSanitize.Media = &Device->Media; - Device->MediaSanitize.MediaClear = NvmExpressMediaClear; - Device->MediaSanitize.MediaPurge = NvmExpressMediaPurge; - Device->MediaSanitize.MediaFormat = NvmExpressMediaFormat; - - ASSERT ( - sizeof (Device->MediaSanitize.SanitizeCapabilities) == - sizeof (Device->Controller->ControllerData->Sanicap) - ); - - CopyMem ( - &(Device->MediaSanitize.SanitizeCapabilities), - &(Device->Controller->ControllerData->Sanicap), - sizeof (Device->MediaSanitize.SanitizeCapabilities) - ); - - // - // Create StorageSecurityProtocol Instance - // - Device->StorageSecurity.ReceiveData = NvmeStorageSecurityReceiveData; - Device->StorageSecurity.SendData = NvmeStorageSecuritySendData; - - // - // Create DiskInfo Protocol instance - // - CopyMem (&Device->NamespaceData, NamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA)); - InitializeDiskInfo (Device); - - // - // Create a Nvm Express Namespace Device Path Node - // - Status = Private->Passthru.BuildDevicePath ( - &Private->Passthru, - Device->NamespaceId, - &NewDevicePathNode - ); - - if (EFI_ERROR (Status)) { - goto Exit; - } - - // - // Append the SSD node to the controller's device path - // - DevicePath = AppendDevicePathNode (ParentDevicePath, NewDevicePathNode); - if (DevicePath == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - - DeviceHandle = NULL; - RemainingDevicePath = DevicePath; - Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle); - if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd (RemainingDevicePath)) { - Status = EFI_ALREADY_STARTED; - FreePool (DevicePath); - goto Exit; - } - - Device->DevicePath = DevicePath; - - // - // Make sure the handle is NULL so we create a new handle - // - Device->DeviceHandle = NULL; - - Status = gBS->InstallMultipleProtocolInterfaces ( - &Device->DeviceHandle, - &gEfiDevicePathProtocolGuid, - Device->DevicePath, - &gEfiBlockIoProtocolGuid, - &Device->BlockIo, - // &gEfiBlockIo2ProtocolGuid, // MU_CHANGE - Request Number of Queues from Controller - // &Device->BlockIo2, // MU_CHANGE - Request Number of Queues from Controller - &gEfiDiskInfoProtocolGuid, - &Device->DiskInfo, - &gMediaSanitizeProtocolGuid, - &Device->MediaSanitize, - NULL - ); - - if (EFI_ERROR (Status)) { - goto Exit; - } - - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - if (NVME_SUPPORT_BLOCKIO2 (Private)) { - // We have multiple data queues, so we can support the BlockIo2 protocol - Status = gBS->InstallMultipleProtocolInterfaces ( - &Device->DeviceHandle, - &gEfiBlockIo2ProtocolGuid, - &Device->BlockIo2, - NULL - ); - - if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - Device->DeviceHandle, - &gEfiDevicePathProtocolGuid, - Device->DevicePath, - &gEfiBlockIoProtocolGuid, - &Device->BlockIo, - &gEfiDiskInfoProtocolGuid, - &Device->DiskInfo, - NULL - ); - - DEBUG ((DEBUG_ERROR, "%a: Failed to install BlockIo2 protocol. Error %r\n", __func__, Status)); - ASSERT_EFI_ERROR (Status); - goto Exit; - } - } - - // MU_CHANGE [END] - Request Number of Queues from Controller - - // - // Check if the NVMe controller supports the Security Send and Security Receive commands - // - if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != 0) { - Status = gBS->InstallProtocolInterface ( - &Device->DeviceHandle, - &gEfiStorageSecurityCommandProtocolGuid, - EFI_NATIVE_INTERFACE, - &Device->StorageSecurity - ); - if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - Device->DeviceHandle, - &gEfiDevicePathProtocolGuid, - Device->DevicePath, - &gEfiBlockIoProtocolGuid, - &Device->BlockIo, - // &gEfiBlockIo2ProtocolGuid, // MU_CHANGE - Request Number of Queues from Controller - // &Device->BlockIo2, // MU_CHANGE - Request Number of Queues from Controller - &gEfiDiskInfoProtocolGuid, - &Device->DiskInfo, - &gMediaSanitizeProtocolGuid, - &Device->MediaSanitize, - NULL - ); - - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - if (NVME_SUPPORT_BLOCKIO2 (Private)) { - // We have multiple data queues, so we need to uninstall the BlockIo2 protocol - gBS->UninstallMultipleProtocolInterfaces ( - Device->DeviceHandle, - &gEfiBlockIo2ProtocolGuid, - &Device->BlockIo2, - NULL - ); - } - - // MU_CHANGE [END] - Request Number of Queues from Controller - - goto Exit; - } - } - - gBS->OpenProtocol ( - Private->ControllerHandle, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **)&DummyInterface, - Private->DriverBindingHandle, - Device->DeviceHandle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - - // - // Dump NvmExpress Identify Namespace Data - // - DEBUG ((DEBUG_INFO, " == NVME IDENTIFY NAMESPACE [%d] DATA ==\n", NamespaceId)); - DEBUG ((DEBUG_INFO, " NSZE : 0x%lx\n", NamespaceData->Nsze)); - DEBUG ((DEBUG_INFO, " NCAP : 0x%lx\n", NamespaceData->Ncap)); - DEBUG ((DEBUG_INFO, " NUSE : 0x%lx\n", NamespaceData->Nuse)); - DEBUG ((DEBUG_INFO, " LBAF0.LBADS : 0x%x\n", (NamespaceData->LbaFormat[0].Lbads))); - - // - // Build controller name for Component Name (2) protocol. - // - CopyMem (Sn, Private->ControllerData->Sn, sizeof (Private->ControllerData->Sn)); - Sn[20] = 0; - CopyMem (Mn, Private->ControllerData->Mn, sizeof (Private->ControllerData->Mn)); - Mn[40] = 0; - UnicodeSPrintAsciiFormat (Device->ModelName, sizeof (Device->ModelName), "%a-%a-%lx", Sn, Mn, NamespaceData->Eui64); - - AddUnicodeString2 ( - "eng", - gNvmExpressComponentName.SupportedLanguages, - &Device->ControllerNameTable, - Device->ModelName, - TRUE - ); - - AddUnicodeString2 ( - "en", - gNvmExpressComponentName2.SupportedLanguages, - &Device->ControllerNameTable, - Device->ModelName, - FALSE - ); - } - -Exit: - if (NamespaceData != NULL) { - FreePool (NamespaceData); - } - - if (NewDevicePathNode != NULL) { - FreePool (NewDevicePathNode); - } - - if (EFI_ERROR (Status) && (Device != NULL) && (Device->DevicePath != NULL)) { - FreePool (Device->DevicePath); - } - - if (EFI_ERROR (Status) && (Device != NULL)) { - FreePool (Device); - } - - return Status; -} - -/** - Discover all Nvm Express device namespaces, and create child handles for them with BlockIo - and DiskInfo protocol instances. - - // MU_CHANGE [BEGIN] - NVMe namespace filtering - When PcdNvmeNamespaceFilterId is 0, all namespaces are enumerated. - When non-zero, only the namespace matching the specified NSID is - discovered and enumerated. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param[in] FilterNsId If 0, discover all namespaces. If non-zero, only discover the namespace - with this NSID. - - @retval EFI_SUCCESS All the namespaces in the device are successfully enumerated. - @return Others Some error occurs when enumerating the namespaces. - -**/ -EFI_STATUS -DiscoverAllNamespaces ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT32 FilterNsId - ) -// MU_CHANGE [END] - NVMe namespace filtering -{ - EFI_STATUS Status; - UINT32 NamespaceId; - EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *Passthru; - - NamespaceId = 0xFFFFFFFF; - Passthru = &Private->Passthru; - - while (TRUE) { - Status = Passthru->GetNextNamespace ( - Passthru, - (UINT32 *)&NamespaceId - ); - - if (EFI_ERROR (Status)) { - break; - } - - // MU_CHANGE [BEGIN] - NVMe namespace filtering - if ((FilterNsId != 0) && (NamespaceId != FilterNsId)) { - continue; - } - - // MU_CHANGE [END] - NVMe namespace filtering - - Status = EnumerateNvmeDevNamespace ( - Private, - NamespaceId - ); - - if (EFI_ERROR (Status)) { - continue; - } - - // MU_CHANGE [BEGIN] - NVMe namespace filtering - if (FilterNsId != 0) { - break; - } - - // MU_CHANGE [END] - NVMe namespace filtering - } - - return EFI_SUCCESS; -} - -/** - Unregisters a Nvm Express device namespace. - - This function removes the protocols installed on the controller handle and - frees the resources allocated for the namespace. - - @param This The pointer to EFI_DRIVER_BINDING_PROTOCOL instance. - @param Controller The controller handle of the namespace. - @param Handle The child handle. - - @retval EFI_SUCCESS The namespace is successfully unregistered. - @return Others Some error occurs when unregistering the namespace. - -**/ -EFI_STATUS -UnregisterNvmeNamespace ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_HANDLE Handle - ) -{ - EFI_STATUS Status; - EFI_STATUS BlockIo2Status; // MU_CHANGE - Request Number of Queues from Controller - EFI_BLOCK_IO_PROTOCOL *BlockIo; - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurity; - BOOLEAN IsEmpty; - EFI_TPL OldTpl; - VOID *DummyInterface; - - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - BlockIo = NULL; - BlockIo2Status = EFI_SUCCESS; - // MU_CHANGE [END] - Request Number of Queues from Controller - - Status = gBS->OpenProtocol ( - Handle, - &gEfiBlockIoProtocolGuid, - (VOID **)&BlockIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (BlockIo); - - // - // Wait for the device's asynchronous I/O queue to become empty. - // - while (TRUE) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - IsEmpty = IsListEmpty (&Device->AsyncQueue); - gBS->RestoreTPL (OldTpl); - - if (IsEmpty) { - break; - } - - gBS->Stall (100); - } - - // - // Close the child handle - // - gBS->CloseProtocol ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - This->DriverBindingHandle, - Handle - ); - - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - // - // If BlockIo2 is installed, uninstall it. - // - if (NVME_SUPPORT_BLOCKIO2 (Device->Controller)) { - BlockIo2Status = gBS->UninstallMultipleProtocolInterfaces ( - Handle, - &gEfiBlockIo2ProtocolGuid, - &Device->BlockIo2, - NULL - ); - - if (EFI_ERROR (BlockIo2Status)) { - DEBUG ((DEBUG_ERROR, "%a: Failed to uninstall BlockIo2 protocol\n", __func__)); - } - } - - // MU_CHANGE [END] - Request Number of Queues from Controller - // - // The Nvm Express driver installs the BlockIo and DiskInfo in the DriverBindingStart(). - // Here should uninstall both of them. - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - Handle, - &gEfiDevicePathProtocolGuid, - Device->DevicePath, - &gEfiBlockIoProtocolGuid, - &Device->BlockIo, - // &gEfiBlockIo2ProtocolGuid, // MU_CHANGE - Request Number of Queues from Controller - // &Device->BlockIo2, // MU_CHANGE - Request Number of Queues from Controller - &gEfiDiskInfoProtocolGuid, - &Device->DiskInfo, - &gMediaSanitizeProtocolGuid, - &Device->MediaSanitize, - NULL - ); - - if (EFI_ERROR (Status) || EFI_ERROR (BlockIo2Status)) { - // MU_CHANGE - Request Number of Queues from Controller - gBS->OpenProtocol ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **)&DummyInterface, - This->DriverBindingHandle, - Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - return Status; - } - - // - // If Storage Security Command Protocol is installed, then uninstall this protocol. - // - Status = gBS->OpenProtocol ( - Handle, - &gEfiStorageSecurityCommandProtocolGuid, - (VOID **)&StorageSecurity, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (!EFI_ERROR (Status)) { - Status = gBS->UninstallProtocolInterface ( - Handle, - &gEfiStorageSecurityCommandProtocolGuid, - &Device->StorageSecurity - ); - if (EFI_ERROR (Status)) { - gBS->OpenProtocol ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **)&DummyInterface, - This->DriverBindingHandle, - Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - return Status; - } - } - - if (Device->DevicePath != NULL) { - FreePool (Device->DevicePath); - } - - if (Device->ControllerNameTable != NULL) { - FreeUnicodeStringTable (Device->ControllerNameTable); - } - - FreePool (Device); - - return EFI_SUCCESS; -} - -/** - Call back function when the timer event is signaled. - - @param[in] Event The Event this notify function registered to. - @param[in] Context Pointer to the context data registered to the - Event. - -**/ -VOID -EFIAPI -ProcessAsyncTaskList ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_PCI_IO_PROTOCOL *PciIo; - NVME_CQ *Cq; - UINT16 QueueId; - UINT32 Data; - LIST_ENTRY *Link; - LIST_ENTRY *NextLink; - NVME_PASS_THRU_ASYNC_REQ *AsyncRequest; - NVME_BLKIO2_SUBTASK *Subtask; - NVME_BLKIO2_REQUEST *BlkIo2Request; - EFI_BLOCK_IO2_TOKEN *Token; - BOOLEAN HasNewItem; - EFI_STATUS Status; - // MU_CHANGE - Support alternative hardware queue sizes in NVME driver - UINT16 QueueSize = PcdGetBool (PcdSupportAlternativeQueueSize) ? - NVME_ALTERNATIVE_MAX_QUEUE_SIZE : NVME_ASYNC_CCQ_SIZE; - - Private = (NVME_CONTROLLER_PRIVATE_DATA *)Context; - QueueId = 2; - Cq = Private->CqBuffer[QueueId] + Private->CqHdbl[QueueId].Cqh; - HasNewItem = FALSE; - PciIo = Private->PciIo; - - // - // Submit asynchronous subtasks to the NVMe Submission Queue - // - for (Link = GetFirstNode (&Private->UnsubmittedSubtasks); - !IsNull (&Private->UnsubmittedSubtasks, Link); - Link = NextLink) - { - NextLink = GetNextNode (&Private->UnsubmittedSubtasks, Link); - Subtask = NVME_BLKIO2_SUBTASK_FROM_LINK (Link); - BlkIo2Request = Subtask->BlockIo2Request; - Token = BlkIo2Request->Token; - RemoveEntryList (Link); - BlkIo2Request->UnsubmittedSubtaskNum--; - - // - // If any previous subtask fails, do not process subsequent ones. - // - if (Token->TransactionStatus != EFI_SUCCESS) { - if (IsListEmpty (&BlkIo2Request->SubtasksQueue) && - BlkIo2Request->LastSubtaskSubmitted && - (BlkIo2Request->UnsubmittedSubtaskNum == 0)) - { - // - // Remove the BlockIo2 request from the device asynchronous queue. - // - RemoveEntryList (&BlkIo2Request->Link); - FreePool (BlkIo2Request); - gBS->SignalEvent (Token->Event); - } - - FreePool (Subtask->CommandPacket->NvmeCmd); - FreePool (Subtask->CommandPacket->NvmeCompletion); - FreePool (Subtask->CommandPacket); - FreePool (Subtask); - - continue; - } - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - Subtask->NamespaceId, - Subtask->CommandPacket, - Subtask->Event - ); - if (Status == EFI_NOT_READY) { - InsertHeadList (&Private->UnsubmittedSubtasks, Link); - BlkIo2Request->UnsubmittedSubtaskNum++; - break; - } else if (EFI_ERROR (Status)) { - Token->TransactionStatus = EFI_DEVICE_ERROR; - - if (IsListEmpty (&BlkIo2Request->SubtasksQueue) && - Subtask->IsLast) - { - // - // Remove the BlockIo2 request from the device asynchronous queue. - // - RemoveEntryList (&BlkIo2Request->Link); - FreePool (BlkIo2Request); - gBS->SignalEvent (Token->Event); - } - - FreePool (Subtask->CommandPacket->NvmeCmd); - FreePool (Subtask->CommandPacket->NvmeCompletion); - FreePool (Subtask->CommandPacket); - FreePool (Subtask); - } else { - InsertTailList (&BlkIo2Request->SubtasksQueue, Link); - if (Subtask->IsLast) { - BlkIo2Request->LastSubtaskSubmitted = TRUE; - } - } - } - - while (Cq->Pt != Private->Pt[QueueId]) { - ASSERT (Cq->Sqid == QueueId); - - HasNewItem = TRUE; - - // - // Find the command with given Command Id. - // - for (Link = GetFirstNode (&Private->AsyncPassThruQueue); - !IsNull (&Private->AsyncPassThruQueue, Link); - Link = NextLink) - { - NextLink = GetNextNode (&Private->AsyncPassThruQueue, Link); - AsyncRequest = NVME_PASS_THRU_ASYNC_REQ_FROM_THIS (Link); - if (AsyncRequest->CommandId == Cq->Cid) { - // - // Copy the Respose Queue entry for this command to the callers - // response buffer. - // - CopyMem ( - AsyncRequest->Packet->NvmeCompletion, - Cq, - sizeof (EFI_NVM_EXPRESS_COMPLETION) - ); - - // MS_HYP_CHANGE BEGIN - // Copy back data and release the bounce buffers - - if (AsyncRequest->Packet->NvmeCmd->Cdw0.Opcode & BIT1) { - if (AsyncRequest->TransferBouncePageList != NULL) { - NvmExpressCopyBouncePagesToExternalBuffer ( - AsyncRequest->Packet->TransferBuffer, - AsyncRequest->Packet->TransferLength, - AsyncRequest->TransferBouncePageList, - FALSE - ); - NvmExpressReleaseBouncePages ( - Private, - AsyncRequest->TransferBouncePageList - ); - } - - if (AsyncRequest->MetadataBouncePageList != NULL) { - NvmExpressCopyBouncePagesToExternalBuffer ( - AsyncRequest->Packet->MetadataBuffer, - AsyncRequest->Packet->MetadataLength, - AsyncRequest->MetadataBouncePageList, - FALSE - ); - NvmExpressReleaseBouncePages ( - Private, - AsyncRequest->MetadataBouncePageList - ); - } - } - - // MS_HYP_CHANGE END - - // - // Free the resources allocated before cmd submission - // - if (AsyncRequest->MapData != NULL) { - PciIo->Unmap (PciIo, AsyncRequest->MapData); - } - - if (AsyncRequest->MapMeta != NULL) { - PciIo->Unmap (PciIo, AsyncRequest->MapMeta); - } - - if (AsyncRequest->MapPrpList != NULL) { - PciIo->Unmap (PciIo, AsyncRequest->MapPrpList); - } - - if (AsyncRequest->PrpListHost != NULL) { - // MS_HYP_CHANGE BEGIN - if (IsIsolated ()) { - NvmExpressMakeAddressRangePrivate (&AsyncRequest->PrpListHostVisibilityContext, AsyncRequest->PrpListHost); - } - - // MS_HYP_CHANGE END - - PciIo->FreeBuffer ( - PciIo, - AsyncRequest->PrpListNo, - AsyncRequest->PrpListHost - ); - } - - RemoveEntryList (Link); - gBS->SignalEvent (AsyncRequest->CallerEvent); - FreePool (AsyncRequest); - - // - // Update submission queue head. - // - Private->AsyncSqHead = Cq->Sqhd; - break; - } - } - - Private->CqHdbl[QueueId].Cqh++; - // MU_CHANGE - Support alternative hardware queue sizes in NVME driver - if (Private->CqHdbl[QueueId].Cqh > MIN (QueueSize, Private->Cap.Mqes)) { - Private->CqHdbl[QueueId].Cqh = 0; - Private->Pt[QueueId] ^= 1; - } - - Cq = Private->CqBuffer[QueueId] + Private->CqHdbl[QueueId].Cqh; - } - - if (HasNewItem) { - Data = ReadUnaligned32 ((UINT32 *)&Private->CqHdbl[QueueId]); - PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CQHDBL_OFFSET (QueueId, Private->Cap.Dstrd), - 1, - &Data - ); - } -} - -/** - Tests to see if this driver supports a given controller. If a child device is provided, - it further tests to see if this driver supports creating a handle for the specified child device. - - This function checks to see if the driver specified by This supports the device specified by - ControllerHandle. Drivers will typically use the device path attached to - ControllerHandle and/or the services from the bus I/O abstraction attached to - ControllerHandle to determine if the driver supports ControllerHandle. This function - may be called many times during platform initialization. In order to reduce boot times, the tests - performed by this function must be very small, and take as little time as possible to execute. This - function must not change the state of any hardware devices, and this function must be aware that the - device specified by ControllerHandle may already be managed by the same driver or a - different driver. This function must match its calls to AllocatePages() with FreePages(), - AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). - Since ControllerHandle may have been previously started by the same driver, if a protocol is - already in the opened state, then it must not be closed with CloseProtocol(). This is required - to guarantee the state of ControllerHandle is not modified by this function. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to test. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For bus drivers, if this parameter is not NULL, then - the bus driver must determine if the bus controller specified - by ControllerHandle and the child controller specified - by RemainingDevicePath are both supported by this - bus driver. - - @retval EFI_SUCCESS The device specified by ControllerHandle and - RemainingDevicePath is supported by the driver specified by This. - @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by the driver - specified by This. - @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by a different - driver or an application that requires exclusive access. - Currently not implemented. - @retval EFI_UNSUPPORTED The device specified by ControllerHandle and - RemainingDevicePath is not supported by the driver specified by This. -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_DEV_PATH_PTR DevicePathNode; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 ClassCode[3]; - - // - // Check whether device path is valid - // - if (RemainingDevicePath != NULL) { - // - // Check if RemainingDevicePath is the End of Device Path Node, - // if yes, go on checking other conditions - // - if (!IsDevicePathEnd (RemainingDevicePath)) { - // - // If RemainingDevicePath isn't the End of Device Path Node, - // check its validation - // - DevicePathNode.DevPath = RemainingDevicePath; - - if ((DevicePathNode.DevPath->Type != MESSAGING_DEVICE_PATH) || - (DevicePathNode.DevPath->SubType != MSG_NVME_NAMESPACE_DP) || - (DevicePathNodeLength (DevicePathNode.DevPath) != sizeof (NVME_NAMESPACE_DEVICE_PATH))) - { - return EFI_UNSUPPORTED; - } - } - } - - // - // Open the EFI Device Path protocol needed to perform the supported test - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **)&ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Close protocol, don't use device path protocol in the Support() function - // - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - // - // Attempt to Open PCI I/O Protocol - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Now further check the PCI header: Base class (offset 0x0B) and Sub Class (offset 0x0A). - // This controller should be a Nvm Express controller. - // - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - PCI_CLASSCODE_OFFSET, - sizeof (ClassCode), - ClassCode - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Examine Nvm Express controller PCI Configuration table fields - // - if ((ClassCode[0] != PCI_IF_NVMHCI) || (ClassCode[1] != PCI_CLASS_MASS_STORAGE_NVM) || (ClassCode[2] != PCI_CLASS_MASS_STORAGE)) { - Status = EFI_UNSUPPORTED; - } - -Done: - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return Status; -} - -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - -/** - Unmap the queues from PciIo and free the buffers allocated. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS The queues are successfully cleaned up. - @return Others Some error occurs when cleaning up the queues. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverCleanUpQueues ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - EFI_STATUS Status; - EFI_STATUS ReturnStatus; - UINTN QueuePairPageCount; - - ReturnStatus = EFI_SUCCESS; - - if (Private == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Admin Queue Clean-up - // - if (Private->Mapping != NULL) { - Status = Private->PciIo->Unmap (Private->PciIo, Private->Mapping); - if (EFI_ERROR (Status)) { - ReturnStatus = Status; - DEBUG ((DEBUG_ERROR, "%a: Unmap Admin Queue Mapping failed %r\n", __func__, Status)); - ASSERT_EFI_ERROR (Status); - } - - Private->Mapping = NULL; - } - - if (Private->Buffer != NULL) { - QueuePairPageCount = NVME_SQ_SIZE_IN_PAGES (Private, 0) + NVME_CQ_SIZE_IN_PAGES (Private, 0); - - // MS_HYP_CHANGE BEGIN - if (IsIsolated ()) { - NvmExpressMakeAddressRangePrivate (&Private->QueueVisibilityContext, Private->Buffer); - - } - // MS_HYP_CHANGE END - - Status = Private->PciIo->FreeBuffer (Private->PciIo, QueuePairPageCount, Private->Buffer); - - if (EFI_ERROR (Status)) { - ReturnStatus = Status; - DEBUG ((DEBUG_ERROR, "%a: FreeBuffer Buffer failed %r\n", __func__, Status)); - ASSERT_EFI_ERROR (Status); - } - - Private->Buffer = NULL; - } - - // - // I/O Queue Clean-up - // - if (Private->IoQueueMapping != NULL) { - Status = Private->PciIo->Unmap (Private->PciIo, Private->IoQueueMapping); - - if (EFI_ERROR (Status)) { - ReturnStatus = Status; - DEBUG ((DEBUG_ERROR, "%a: Unmap IoQueueMapping failed %r\n", __func__, Status)); - ASSERT_EFI_ERROR (Status); - } - - Private->IoQueueMapping = NULL; - } - - if (Private->IoQueueBuffer != NULL) { - // Using the first data queue size for the number of pages required for the data queues - QueuePairPageCount = NVME_SQ_SIZE_IN_PAGES (Private, 1) + NVME_CQ_SIZE_IN_PAGES (Private, 1); - - // MS_HYP_CHANGE BEGIN - if (IsIsolated()) { - NvmExpressMakeAddressRangePrivate (&Private->IoQueueVisibilityContext, Private->IoQueueBuffer); - } - // MS_HYP_CHANGE END - Status = Private->PciIo->FreeBuffer (Private->PciIo, QueuePairPageCount*Private->NumberOfIoQueuePairs, Private->IoQueueBuffer); - - if (EFI_ERROR (Status)) { - ReturnStatus = Status; - DEBUG ((DEBUG_ERROR, "%a: FreeBuffer IoQueueBuffer failed %r\n", __func__, Status)); - ASSERT_EFI_ERROR (Status); - } - - Private->IoQueueBuffer = NULL; - } - - return ReturnStatus; -} - -// MU_CHANGE [END] - Allocate IO Queue Buffer - -/** - Starts a device controller or a bus controller. - - The Start() function is designed to be invoked from the EFI boot service ConnectController(). - As a result, much of the error checking on the parameters to Start() has been moved into this - common boot service. It is legal to call Start() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE. - 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned - EFI_DEVICE_PATH_PROTOCOL. - 3. Prior to calling Start(), the Supported() function for the driver specified by This must - have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to start. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For a bus driver, if this parameter is NULL, then handles - for all the children of Controller are created by this driver. - If this parameter is not NULL and the first Device Path Node is - not the End of Device Path Node, then only the handle for the - child device specified by the first Device Path Node of - RemainingDevicePath is created by this driver. - If the first Device Path Node of RemainingDevicePath is - the End of Device Path Node, no child handle is created by this - driver. - - @retval EFI_SUCCESS The device was started. - @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval Others The driver failded to start the device. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - UINT32 NamespaceId; - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - // EFI_PHYSICAL_ADDRESS MappedAddr; - // UINTN Bytes; - // MU_CHANGE [END] - Allocate IO Queue Buffer - - EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *Passthru; - UINT32 FilterNsId; // MU_CHANGE - NVMe namespace filtering - - - DEBUG ((DEBUG_INFO, "NvmExpressDriverBindingStart: start\n")); - - Private = NULL; - Passthru = NULL; - ParentDevicePath = NULL; - - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **)&ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) { - return Status; - } - - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { - return Status; - } - - // - // Check EFI_ALREADY_STARTED to reuse the original NVME_CONTROLLER_PRIVATE_DATA. - // - if (Status != EFI_ALREADY_STARTED) { - Private = AllocateZeroPool (sizeof (NVME_CONTROLLER_PRIVATE_DATA)); - - if (Private == NULL) { - DEBUG ((DEBUG_ERROR, "NvmExpressDriverBindingStart: allocating pool for Nvme Private Data failed!\n")); - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - - // - // Save original PCI attributes - // - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationGet, - 0, - &Private->PciAttributes - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Enable 64-bit DMA support in the PCI layer. - // - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE, - NULL - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, "NvmExpressDriverBindingStart: failed to enable 64-bit DMA (%r)\n", Status)); - } - - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - // // - // // 6 x 4kB aligned buffers will be carved out of this buffer. - // // 1st 4kB boundary is the start of the admin submission queue. - // // 2nd 4kB boundary is the start of the admin completion queue. - // // 3rd 4kB boundary is the start of I/O submission queue #1. - // // 4th 4kB boundary is the start of I/O completion queue #1. - // // 5th 4kB boundary is the start of I/O submission queue #2. - // // 6th 4kB boundary is the start of I/O completion queue #2. - // // - // // Allocate 6 pages of memory, then map it for bus master read and write. - // // - // Status = PciIo->AllocateBuffer ( - // PciIo, - // AllocateAnyPages, - // EfiBootServicesData, - // 6, - // (VOID **)&Private->Buffer, - // 0 - // ); - // if (EFI_ERROR (Status)) { - // goto Exit; - // } - - - // MS_HYP_CHANGE - Support alternative hardware queue sizes in NVME driver - // Bytes = EFI_PAGES_TO_SIZE (QueuePageCount); - // Status = PciIo->Map ( - // PciIo, - // EfiPciIoOperationBusMasterCommonBuffer, - // Private->Buffer, - // &Bytes, - // &MappedAddr, - // &Private->Mapping - // ); - - // MS_HYP_CHANGE - Support alternative hardware queue sizes in NVME driver - // if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (QueuePageCount))) { - // goto Exit; - // } - - - // Private->BufferPciAddr = (UINT8 *)(UINTN)MappedAddr; - // MU_CHANGE [END] - Allocate IO Queue Buffer - - Private->Signature = NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE; - Private->ControllerHandle = Controller; - Private->ImageHandle = This->DriverBindingHandle; - Private->DriverBindingHandle = This->DriverBindingHandle; - Private->PciIo = PciIo; - Private->ParentDevicePath = ParentDevicePath; - Private->Passthru.Mode = &Private->PassThruMode; - Private->Passthru.PassThru = NvmExpressPassThru; - Private->Passthru.GetNextNamespace = NvmExpressGetNextNamespace; - Private->Passthru.BuildDevicePath = NvmExpressBuildDevicePath; - Private->Passthru.GetNamespace = NvmExpressGetNamespace; - CopyMem (&Private->PassThruMode, &gEfiNvmExpressPassThruMode, sizeof (EFI_NVM_EXPRESS_PASS_THRU_MODE)); - InitializeListHead (&Private->AsyncPassThruQueue); - InitializeListHead (&Private->UnsubmittedSubtasks); - - // MS_HYP_CHANGE BEGIN - // - // Allocate bounce block for isolated VMs - // - - if (NvmExpressIsBounceActive ()) { - InitializeListHead (&Private->BounceBlockListHead); - Status = NvmExpressAllocateBounceBlock (Private, NVME_BOUNCE_BLOCK_SIZE); - if (EFI_ERROR (Status)) { - goto Exit; - } - } - - // MS_HYP_CHANGE END - - Status = NvmeControllerInit (Private); - if (EFI_ERROR (Status)) { - goto Exit; - } - - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - - // - // Start the asynchronous I/O completion monitor - // The ProcessAsyncTaskList event and NVME_HC_ASYNC_TIMER timer are only used for the BlockIo2 protocol, - // which is only installed when the number of IO queues is greater than 1 - // - if (NVME_SUPPORT_BLOCKIO2 (Private)) { - Status = gBS->CreateEvent ( - EVT_TIMER | EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - ProcessAsyncTaskList, - Private, - &Private->TimerEvent - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - Status = gBS->SetTimer ( - Private->TimerEvent, - TimerPeriodic, - NVME_HC_ASYNC_TIMER - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - } - - // MU_CHANGE [END] - Request Number of Queues from Controller - - Status = gBS->InstallMultipleProtocolInterfaces ( - &Controller, - &gEfiNvmExpressPassThruProtocolGuid, - &Private->Passthru, - NULL - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - NvmeRegisterShutdownNotification (); - } else { - Status = gBS->OpenProtocol ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **)&Passthru, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (Passthru); - } - - // MU_CHANGE [BEGIN] - NVMe namespace filtering - FilterNsId = PcdGet32 (PcdNvmeNamespaceFilterId); - // MU_CHANGE [END] - NVMe namespace filtering - - if (RemainingDevicePath == NULL) { - // - // Enumerate all NVME namespaces in the controller - // - // MU_CHANGE [BEGIN] - NVMe namespace filtering - Status = DiscoverAllNamespaces ( - Private, - FilterNsId - ); - // MU_CHANGE [END] - NVMe namespace filtering - } else if (!IsDevicePathEnd (RemainingDevicePath)) { - // - // Enumerate the specified NVME namespace - // - Status = Private->Passthru.GetNamespace ( - &Private->Passthru, - RemainingDevicePath, - &NamespaceId - ); - - if (!EFI_ERROR (Status)) { - // MU_CHANGE [BEGIN] - NVMe namespace filtering - if ((FilterNsId == 0) || - (NamespaceId == FilterNsId)) - { - Status = EnumerateNvmeDevNamespace ( - Private, - NamespaceId - ); - } - - // MU_CHANGE [END] - NVMe namespace filtering - } - } - - DEBUG ((DEBUG_INFO, "NvmExpressDriverBindingStart: end successfully\n")); - return EFI_SUCCESS; - -Exit: - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - // if ((Private != NULL) && (Private->Mapping != NULL)) { - // PciIo->Unmap (PciIo, Private->Mapping); - // } - // - // if ((Private != NULL) && (Private->Buffer != NULL)) { - // PciIo->FreeBuffer (PciIo, 6, Private->Buffer); - // } - - Status = NvmExpressDriverCleanUpQueues (Private); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: NvmExpressDriverCleanUpQueues failed %r\n", __func__, Status)); - } - - // MU_CHANGE [END] - Allocate IO Queue Buffer - - if ((Private != NULL) && (Private->ControllerData != NULL)) { - FreePool (Private->ControllerData); - } - - if (Private != NULL) { - if (Private->TimerEvent != NULL) { - gBS->CloseEvent (Private->TimerEvent); - } - - FreePool (Private); - } - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - DEBUG ((DEBUG_INFO, "NvmExpressDriverBindingStart: end with %r\n", Status)); - - return Status; -} - -/** - Stops a device controller or a bus controller. - - The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). - As a result, much of the error checking on the parameters to Stop() has been moved - into this common boot service. It is legal to call Stop() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this - same driver's Start() function. - 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid - EFI_HANDLE. In addition, all of these handles must have been created in this driver's - Start() function, and the Start() function must have called OpenProtocol() on - ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle A handle to the device being stopped. The handle must - support a bus specific I/O protocol for the driver - to use to stop the device. - @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -{ - EFI_STATUS Status; - BOOLEAN AllChildrenStopped; - UINTN Index; - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *PassThru; - BOOLEAN IsEmpty; - EFI_TPL OldTpl; - - if (NumberOfChildren == 0) { - Status = gBS->OpenProtocol ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **)&PassThru, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (!EFI_ERROR (Status)) { - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (PassThru); - - // - // Wait for the asynchronous PassThru queue to become empty. - // - while (TRUE) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - IsEmpty = IsListEmpty (&Private->AsyncPassThruQueue) && - IsListEmpty (&Private->UnsubmittedSubtasks); - gBS->RestoreTPL (OldTpl); - - if (IsEmpty) { - break; - } - - gBS->Stall (100); - } - - gBS->UninstallMultipleProtocolInterfaces ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - PassThru, - NULL - ); - - if (Private->TimerEvent != NULL) { - gBS->CloseEvent (Private->TimerEvent); - } - - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - // if (Private->Mapping != NULL) { - // Private->PciIo->Unmap (Private->PciIo, Private->Mapping); - // } - // - // if (Private->Buffer != NULL) { - // Private->PciIo->FreeBuffer (Private->PciIo, 6, Private->Buffer); - // } - - Status = NvmExpressDriverCleanUpQueues (Private); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: NvmExpressDriverCleanUpQueues failed %r\n", __func__, Status)); - } - - // MU_CHANGE [END] - Allocate IO Queue Buffer - - NvmExpressFreeAllBounceBlocks (Private); // MS_HYP_CHANGE - FreePool (Private->ControllerData); - FreePool (Private); - } - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - NvmeUnregisterShutdownNotification (); - - return EFI_SUCCESS; - } - - AllChildrenStopped = TRUE; - - for (Index = 0; Index < NumberOfChildren; Index++) { - Status = UnregisterNvmeNamespace (This, Controller, ChildHandleBuffer[Index]); - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - } - } - - if (!AllChildrenStopped) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - This is the unload handle for the NVM Express driver. - - Disconnect the driver specified by ImageHandle from the NVMe device in the handle database. - Uninstall all the protocols installed in the driver. - - @param[in] ImageHandle The drivers' driver image. - - @retval EFI_SUCCESS The image is unloaded. - @retval Others Failed to unload the image. - -**/ -EFI_STATUS -EFIAPI -NvmExpressUnload ( - IN EFI_HANDLE ImageHandle - ) -{ - EFI_STATUS Status; - EFI_HANDLE *DeviceHandleBuffer; - UINTN DeviceHandleCount; - UINTN Index; - EFI_COMPONENT_NAME_PROTOCOL *ComponentName; - EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2; - - // - // Get the list of the device handles managed by this driver. - // If there is an error getting the list, then means the driver - // doesn't manage any device. At this way, we would only close - // those protocols installed at image handle. - // - DeviceHandleBuffer = NULL; - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiNvmExpressPassThruProtocolGuid, - NULL, - &DeviceHandleCount, - &DeviceHandleBuffer - ); - - if (!EFI_ERROR (Status)) { - // - // Disconnect the driver specified by ImageHandle from all - // the devices in the handle database. - // - for (Index = 0; Index < DeviceHandleCount; Index++) { - Status = gBS->DisconnectController ( - DeviceHandleBuffer[Index], - ImageHandle, - NULL - ); - if (EFI_ERROR (Status)) { - goto EXIT; - } - } - } - - // - // Uninstall all the protocols installed in the driver entry point - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - ImageHandle, - &gEfiDriverBindingProtocolGuid, - &gNvmExpressDriverBinding, - &gEfiDriverSupportedEfiVersionProtocolGuid, - &gNvmExpressDriverSupportedEfiVersion, - NULL - ); - - if (EFI_ERROR (Status)) { - goto EXIT; - } - - // - // Note we have to one by one uninstall the following protocols. - // It's because some of them are optionally installed based on - // the following PCD settings. - // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable - // gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable - // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable - // gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable - // - Status = gBS->HandleProtocol ( - ImageHandle, - &gEfiComponentNameProtocolGuid, - (VOID **)&ComponentName - ); - if (!EFI_ERROR (Status)) { - gBS->UninstallProtocolInterface ( - ImageHandle, - &gEfiComponentNameProtocolGuid, - ComponentName - ); - } - - Status = gBS->HandleProtocol ( - ImageHandle, - &gEfiComponentName2ProtocolGuid, - (VOID **)&ComponentName2 - ); - if (!EFI_ERROR (Status)) { - gBS->UninstallProtocolInterface ( - ImageHandle, - &gEfiComponentName2ProtocolGuid, - ComponentName2 - ); - } - - Status = EFI_SUCCESS; - -EXIT: - // - // Free the buffer containing the list of handles from the handle database - // - if (DeviceHandleBuffer != NULL) { - gBS->FreePool (DeviceHandleBuffer); - } - - return Status; -} - -/** - The entry point for Nvm Express driver, used to install Nvm Express driver on the ImageHandle. - - @param ImageHandle The firmware allocated handle for this driver image. - @param SystemTable Pointer to the EFI system table. - - @retval EFI_SUCCESS Driver loaded. - @retval other Driver not loaded. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverEntry ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gNvmExpressDriverBinding, - ImageHandle, - &gNvmExpressComponentName, - &gNvmExpressComponentName2 - ); - ASSERT_EFI_ERROR (Status); - - // - // Install EFI Driver Supported EFI Version Protocol required for - // EFI drivers that are on PCI and other plug in cards. - // - gNvmExpressDriverSupportedEfiVersion.FirmwareVersion = 0x00020028; - Status = gBS->InstallMultipleProtocolInterfaces ( - &ImageHandle, - &gEfiDriverSupportedEfiVersionProtocolGuid, - &gNvmExpressDriverSupportedEfiVersion, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // MS_HYP_CHANGE BEGIN - if (NvmExpressIsBounceActive ()) { - Status = NvmExpressInitializeBounce (); - ASSERT_EFI_ERROR (Status); - } - - // MS_HYP_CHANGE END - - return Status; -} diff --git a/MsvmPkg/NvmExpressDxe/NvmExpress.h b/MsvmPkg/NvmExpressDxe/NvmExpress.h deleted file mode 100644 index a265825474..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpress.h +++ /dev/null @@ -1,874 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - (C) Copyright 2016 Hewlett Packard Enterprise Development LP
- Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
- Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _EFI_NVM_EXPRESS_H_ -#define _EFI_NVM_EXPRESS_H_ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -typedef struct _NVME_CONTROLLER_PRIVATE_DATA NVME_CONTROLLER_PRIVATE_DATA; -typedef struct _NVME_DEVICE_PRIVATE_DATA NVME_DEVICE_PRIVATE_DATA; -typedef struct _NVME_QUEUE_SIZE_DATA NVME_QUEUE_SIZE_DATA; // MU_CHANGE - Allocate IO Queue Buffer - -#include "NvmExpressBlockIo.h" -#include "NvmExpressBounce.h" // MS_HYP_CHANGE -#include "NvmExpressDiskInfo.h" -#include "NvmExpressHci.h" -#include "NvmExpressMediaSanitize.h" - -extern EFI_DRIVER_BINDING_PROTOCOL gNvmExpressDriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gNvmExpressComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gNvmExpressComponentName2; -extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gNvmExpressDriverSupportedEfiVersion; - -#define PCI_CLASS_MASS_STORAGE_NVM 0x08 // mass storage sub-class non-volatile memory. -#define PCI_IF_NVMHCI 0x02 // mass storage programming interface NVMHCI. - -#define NVME_ASQ_SIZE 1 // Number of admin submission queue entries, which is 0-based -#define NVME_ACQ_SIZE 1 // Number of admin completion queue entries, which is 0-based - -#define NVME_CSQ_SIZE 1 // Number of I/O submission queue entries, which is 0-based -#define NVME_CCQ_SIZE 1 // Number of I/O completion queue entries, which is 0-based - -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer -// NVM Express 2.0e specification, section 5.17.1 Identify Controller Data Structure (CNS 01h) -// The specification defines these numbers as the minimum and standard values. They are what this driver supports. -// The values are in bytes and are reported as a power of 2. -#define NVME_IOSQES_MIN 6 // I/O submission queue entry size -#define NVME_IOCQES_MIN 4 // I/O completion queue entry size -// MU_CHANGE [END] - Allocate IO Queue Buffer - -// -// Number of asynchronous I/O submission queue entries, which is 0-based. -// The asynchronous I/O submission queue size is 4kB in total. -// -#define NVME_ASYNC_CSQ_SIZE 63 -// -// Number of asynchronous I/O completion queue entries, which is 0-based. -// The asynchronous I/O completion queue size is 4kB in total. -// -#define NVME_ASYNC_CCQ_SIZE 255 - -// MU_CHANGE [BEGIN] - Request Number of Queues from Controller -// Maximum number of queue pairs supported by the driver, including the admin queues. -// Queue 0 - Admin -// Queue 1 - Blocking I/O (BlockIo Protocol) -// Queue 2 - Asynchronous I/O (BlockIo2 Protocol) -#define NVME_MAX_QUEUES 3 - -// Returns if the controller supports the BlockIo2 protocol. -// The BlockIo2 protocol is only supported if the controller has more than 1 queue pair allocated -#define NVME_SUPPORT_BLOCKIO2(ContollerPointer) (((ContollerPointer)->NumberOfIoQueuePairs) > 1) -// MU_CHANGE [END] - Request Number of Queues from Controller - -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer -// -// Returns the number of pages required for a submission/completion queue -// The Indices are the same as above, 0 for admin, 1 for blocking I/O, 2 for async I/O. -// -#define NVME_SQ_SIZE_IN_PAGES(ControllerPointer, Index) \ - EFI_SIZE_TO_PAGES(((ControllerPointer)->SqData[(Index)].NumberOfEntries * (UINTN)LShiftU64 (2, (ControllerPointer)->SqData[(Index)].EntrySize))) - -#define NVME_CQ_SIZE_IN_PAGES(ControllerPointer, Index) \ - EFI_SIZE_TO_PAGES(((ControllerPointer)->CqData[(Index)].NumberOfEntries * (UINTN)LShiftU64 (2, (ControllerPointer)->CqData[(Index)].EntrySize))) - -// MU_CHANGE [END] - Allocate IO Queue Buffer - -// -// FormatNVM Admin Command LBA Format (LBAF) Mask -// -#define NVME_LBA_FORMATNVM_LBAF_MASK 0xF - -// -// NVMe Completion Queue Entry Bits, Fields, Masks -// -#define NVME_CQE_STATUS_FIELD_MASK 0xFFFF0000 -#define NVME_CQE_STATUS_FIELD_OFFSET 16 -#define NVME_CQE_STATUS_FIELD_SCT_MASK 0x0E00 -#define NVME_CQE_STATUS_FIELD_SCT_OFFSET 0x9 -#define NVME_CQE_STATUS_FIELD_SC_MASK 0x1FE -#define NVME_CQE_STATUS_FIELD_SC_OFFSET 0x01 -#define NVME_CQE_SCT_GENERIC_CMD_STATUS 0x0 -#define NVME_CQE_SCT_CMD_SPECIFIC_STATUS 0x1 -#define NVME_CQE_SCT_MEDIA_DATA_INTEGRITY_ERRORS_STATUS 0x2 -#define NVME_CQE_SCT_PATH_RELATED_STATUS 0x3 -#define NVME_CQE_SC_SUCCESSFUL_COMPLETION 0x00 -#define NVME_CQE_SC_INVALID_CMD_OPCODE 0x01 -#define NVME_CQE_SC_INVALID_FIELD_IN_CMD 0x02 - -#define NVME_ALL_NAMESPACES 0xFFFFFFFF - -// MU_CHANGE [BEGIN] - Support alternative hardware queue sizes in NVME driver - -// -// NVMe DXE to accommodate hardware which requires queue size 255. -// Driver supports queue size up to 255 (4 page SQ buffer). -// DXE driver creates queue size MIN(Cap.Mqes, NVME_MAX_QUEUE_SIZE) for all queues. -// Driver allocates queue buffer to support 255 max queue size. -// Each submission queue buffer is allocated as 64B * 256 = 4 * 4kB = 4 pages. -// Each completion queue buffer is allocated as 16B * 256 = 4kB = 1 page. -// -#define NVME_ALTERNATIVE_MAX_QUEUE_SIZE 255 - -// MU_CHANGE [END] - Support alternative hardware queue sizes in NVME driver - -#define NVME_CONTROLLER_ID 0 - -// -// MS_HYP_CHANGE: Extended I/O timeout for Azure -#define NVME_GENERIC_TIMEOUT EFI_TIMER_PERIOD_SECONDS (120) - -// -// Nvme async transfer timer interval, set by experience. -// -#define NVME_HC_ASYNC_TIMER EFI_TIMER_PERIOD_MILLISECONDS (1) - -// -// Unique signature for private data structure. -// -#define NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('N','V','M','E') -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer -#define NVME_INVALID_VID_DID 0xFFFF - -// -// Nvme queue data -// -struct _NVME_QUEUE_SIZE_DATA { - UINT32 NumberOfEntries; // in number of entries - UINT8 EntrySize; // in bytes, as a power of 2 -}; - -// MU_CHANGE [END] - Allocate IO Queue Buffer - -// -// Nvme private data structure. -// -struct _NVME_CONTROLLER_PRIVATE_DATA { - UINT32 Signature; - - EFI_HANDLE ControllerHandle; - EFI_HANDLE ImageHandle; - EFI_HANDLE DriverBindingHandle; - - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 PciAttributes; - - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - - EFI_NVM_EXPRESS_PASS_THRU_MODE PassThruMode; - EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL Passthru; - - // - // pointer to identify controller data - // - NVME_ADMIN_CONTROLLER_DATA *ControllerData; - - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - // - // Number of Queues Allocated by the controller - // UEFI always uses a 1:1 submission:completion queue allocation so we - // use NumberOfIoQueuePairs to represent the number of data queue pairs allocated. - // NumberOfIoQueuePairs = Nsqa = Ncqa - // - UINT32 NumberOfIoQueuePairs; - // MU_CHANGE [END] - Request Number of Queues from Controller - - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - // - // Queue Size Data - // - NVME_QUEUE_SIZE_DATA SqData[NVME_MAX_QUEUES]; - NVME_QUEUE_SIZE_DATA CqData[NVME_MAX_QUEUES]; - // MU_CHANGE [END] - Allocate IO Queue Buffer - - // - // 6 x 4kB aligned buffers will be carved out of this buffer. - // 1st 4kB boundary is the start of the admin submission queue. - // 2nd 4kB boundary is the start of the admin completion queue. - // 3rd 4kB boundary is the start of I/O submission queue #1. - // 4th 4kB boundary is the start of I/O completion queue #1. - // 5th 4kB boundary is the start of I/O submission queue #2. - // 6th 4kB boundary is the start of I/O completion queue #2. - // - UINT8 *Buffer; - UINT8 *BufferPciAddr; - - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - UINT8 *IoQueueBuffer; - UINT8 *IoQueueBufferPciAddr; - // MU_CHANGE [END] - Allocate IO Queue Buffer - - // - // Pointers to 4kB aligned submission & completion queues. - // - NVME_SQ *SqBuffer[NVME_MAX_QUEUES]; - NVME_CQ *CqBuffer[NVME_MAX_QUEUES]; - NVME_SQ *SqBufferPciAddr[NVME_MAX_QUEUES]; - NVME_CQ *CqBufferPciAddr[NVME_MAX_QUEUES]; - - // - // Submission and completion queue indices. - // - NVME_SQTDBL SqTdbl[NVME_MAX_QUEUES]; - NVME_CQHDBL CqHdbl[NVME_MAX_QUEUES]; - UINT16 AsyncSqHead; - - // - // Flag to indicate internal IO queue creation. - // - BOOLEAN CreateIoQueue; - - UINT8 Pt[NVME_MAX_QUEUES]; - UINT16 Cid[NVME_MAX_QUEUES]; - - // - // Nvme controller capabilities - // - NVME_CAP Cap; - - VOID *Mapping; - VOID *IoQueueMapping; // MU_CHANGE - Allocate IO Queue Buffer - - // - // For Non-blocking operations. - // - EFI_EVENT TimerEvent; - LIST_ENTRY AsyncPassThruQueue; - LIST_ENTRY UnsubmittedSubtasks; - // MS_HYP_CHANGE BEGIN - LIST_ENTRY BounceBlockListHead; - NVME_HOST_VISIBILITY_CONTEXT QueueVisibilityContext; - NVME_HOST_VISIBILITY_CONTEXT IoQueueVisibilityContext; - // MS_HYP_CHANGE END -}; - -#define NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU(a) \ - CR (a, \ - NVME_CONTROLLER_PRIVATE_DATA, \ - Passthru, \ - NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE \ - ) - -// -// Unique signature for private data structure. -// -#define NVME_DEVICE_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('X','S','S','D') - -// -// Nvme device private data structure -// -struct _NVME_DEVICE_PRIVATE_DATA { - UINT32 Signature; - - EFI_HANDLE DeviceHandle; - EFI_HANDLE ControllerHandle; - EFI_HANDLE DriverBindingHandle; - - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - - UINT32 NamespaceId; - UINT64 NamespaceUuid; - - EFI_BLOCK_IO_MEDIA Media; - EFI_BLOCK_IO_PROTOCOL BlockIo; - EFI_BLOCK_IO2_PROTOCOL BlockIo2; - EFI_DISK_INFO_PROTOCOL DiskInfo; - EFI_STORAGE_SECURITY_COMMAND_PROTOCOL StorageSecurity; - - MEDIA_SANITIZE_PROTOCOL MediaSanitize; - - LIST_ENTRY AsyncQueue; - - EFI_LBA NumBlocks; - - CHAR16 ModelName[80]; - NVME_ADMIN_NAMESPACE_DATA NamespaceData; - - NVME_CONTROLLER_PRIVATE_DATA *Controller; -}; - -// -// Statments to retrieve the private data from produced protocols. -// -#define NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO(a) \ - CR (a, \ - NVME_DEVICE_PRIVATE_DATA, \ - BlockIo, \ - NVME_DEVICE_PRIVATE_DATA_SIGNATURE \ - ) - -#define NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2(a) \ - CR (a, \ - NVME_DEVICE_PRIVATE_DATA, \ - BlockIo2, \ - NVME_DEVICE_PRIVATE_DATA_SIGNATURE \ - ) - -#define NVME_DEVICE_PRIVATE_DATA_FROM_DISK_INFO(a) \ - CR (a, \ - NVME_DEVICE_PRIVATE_DATA, \ - DiskInfo, \ - NVME_DEVICE_PRIVATE_DATA_SIGNATURE \ - ) - -#define NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY(a) \ - CR (a, \ - NVME_DEVICE_PRIVATE_DATA, \ - StorageSecurity, \ - NVME_DEVICE_PRIVATE_DATA_SIGNATURE \ - ) - -#define NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE(a) \ - CR (a, \ - NVME_DEVICE_PRIVATE_DATA, \ - MediaSanitize, \ - NVME_DEVICE_PRIVATE_DATA_SIGNATURE \ - ) - -// -// Nvme block I/O 2 request. -// -#define NVME_BLKIO2_REQUEST_SIGNATURE SIGNATURE_32 ('N', 'B', '2', 'R') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - - EFI_BLOCK_IO2_TOKEN *Token; - UINTN UnsubmittedSubtaskNum; - BOOLEAN LastSubtaskSubmitted; - // - // The queue for Nvme read/write sub-tasks of a BlockIo2 request. - // - LIST_ENTRY SubtasksQueue; -} NVME_BLKIO2_REQUEST; - -#define NVME_BLKIO2_REQUEST_FROM_LINK(a) \ - CR (a, NVME_BLKIO2_REQUEST, Link, NVME_BLKIO2_REQUEST_SIGNATURE) - -#define NVME_BLKIO2_SUBTASK_SIGNATURE SIGNATURE_32 ('N', 'B', '2', 'S') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - - BOOLEAN IsLast; - UINT32 NamespaceId; - EFI_EVENT Event; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *CommandPacket; - // - // The BlockIo2 request this subtask belongs to - // - NVME_BLKIO2_REQUEST *BlockIo2Request; -} NVME_BLKIO2_SUBTASK; - -#define NVME_BLKIO2_SUBTASK_FROM_LINK(a) \ - CR (a, NVME_BLKIO2_SUBTASK, Link, NVME_BLKIO2_SUBTASK_SIGNATURE) - -// -// Nvme asynchronous passthru request. -// -#define NVME_PASS_THRU_ASYNC_REQ_SIG SIGNATURE_32 ('N', 'P', 'A', 'R') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet; - UINT16 CommandId; - VOID *MapPrpList; - UINTN PrpListNo; - VOID *PrpListHost; - VOID *MapData; - VOID *MapMeta; - EFI_EVENT CallerEvent; - // MS_HYP_CHANGE BEGIN - PNVME_BOUNCE_PAGE TransferBouncePageList; - PNVME_BOUNCE_PAGE MetadataBouncePageList; - NVME_HOST_VISIBILITY_CONTEXT PrpListHostVisibilityContext; - // MS_HYP_CHANGE END -} NVME_PASS_THRU_ASYNC_REQ; - -#define NVME_PASS_THRU_ASYNC_REQ_FROM_THIS(a) \ - CR (a, \ - NVME_PASS_THRU_ASYNC_REQ, \ - Link, \ - NVME_PASS_THRU_ASYNC_REQ_SIG \ - ) - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -NvmExpressComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -NvmExpressComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - -/** - Tests to see if this driver supports a given controller. If a child device is provided, - it further tests to see if this driver supports creating a handle for the specified child device. - - This function checks to see if the driver specified by This supports the device specified by - ControllerHandle. Drivers will typically use the device path attached to - ControllerHandle and/or the services from the bus I/O abstraction attached to - ControllerHandle to determine if the driver supports ControllerHandle. This function - may be called many times during platform initialization. In order to reduce boot times, the tests - performed by this function must be very small, and take as little time as possible to execute. This - function must not change the state of any hardware devices, and this function must be aware that the - device specified by ControllerHandle may already be managed by the same driver or a - different driver. This function must match its calls to AllocatePages() with FreePages(), - AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). - Since ControllerHandle may have been previously started by the same driver, if a protocol is - already in the opened state, then it must not be closed with CloseProtocol(). This is required - to guarantee the state of ControllerHandle is not modified by this function. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to test. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For bus drivers, if this parameter is not NULL, then - the bus driver must determine if the bus controller specified - by ControllerHandle and the child controller specified - by RemainingDevicePath are both supported by this - bus driver. - - @retval EFI_SUCCESS The device specified by ControllerHandle and - RemainingDevicePath is supported by the driver specified by This. - @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by the driver - specified by This. - @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by a different - driver or an application that requires exclusive access. - Currently not implemented. - @retval EFI_UNSUPPORTED The device specified by ControllerHandle and - RemainingDevicePath is not supported by the driver specified by This. -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Starts a device controller or a bus controller. - - The Start() function is designed to be invoked from the EFI boot service ConnectController(). - As a result, much of the error checking on the parameters to Start() has been moved into this - common boot service. It is legal to call Start() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE. - 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned - EFI_DEVICE_PATH_PROTOCOL. - 3. Prior to calling Start(), the Supported() function for the driver specified by This must - have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to start. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For a bus driver, if this parameter is NULL, then handles - for all the children of Controller are created by this driver. - If this parameter is not NULL and the first Device Path Node is - not the End of Device Path Node, then only the handle for the - child device specified by the first Device Path Node of - RemainingDevicePath is created by this driver. - If the first Device Path Node of RemainingDevicePath is - the End of Device Path Node, no child handle is created by this - driver. - - @retval EFI_SUCCESS The device was started. - @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval Others The driver failded to start the device. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Stops a device controller or a bus controller. - - The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). - As a result, much of the error checking on the parameters to Stop() has been moved - into this common boot service. It is legal to call Stop() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this - same driver's Start() function. - 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid - EFI_HANDLE. In addition, all of these handles must have been created in this driver's - Start() function, and the Start() function must have called OpenProtocol() on - ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle A handle to the device being stopped. The handle must - support a bus specific I/O protocol for the driver - to use to stop the device. - @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -/** - Sends an NVM Express Command Packet to an NVM Express controller or namespace. This function supports - both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the nonblocking - I/O functionality is optional. - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] NamespaceId Is a 32 bit Namespace ID to which the Express HCI command packet will be sent. - A value of 0 denotes the NVM Express controller, a value of all 0FFh in the namespace - ID specifies that the command packet should be sent to all valid namespaces. - @param[in,out] Packet A pointer to the NVM Express HCI Command Packet to send to the NVMe namespace specified - by NamespaceId. - @param[in] Event If nonblocking I/O is not supported then Event is ignored, and blocking I/O is performed. - If Event is NULL, then blocking I/O is performed. If Event is not NULL and non blocking I/O - is supported, then nonblocking I/O is performed, and Event will be signaled when the NVM - Express Command Packet completes. - - @retval EFI_SUCCESS The NVM Express Command Packet was sent by the host. TransferLength bytes were transferred - to, or from DataBuffer. - @retval EFI_BAD_BUFFER_SIZE The NVM Express Command Packet was not executed. The number of bytes that could be transferred - is returned in TransferLength. - @retval EFI_NOT_READY The NVM Express Command Packet could not be sent because the controller is not ready. The caller - may retry again later. - @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the NVM Express Command Packet. - @retval EFI_INVALID_PARAMETER Namespace, or the contents of EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET are invalid. The NVM - Express Command Packet was not sent, so no additional status information is available. - @retval EFI_UNSUPPORTED The command described by the NVM Express Command Packet is not supported by the host adapter. - The NVM Express Command Packet was not sent, so no additional status information is available. - @retval EFI_TIMEOUT A timeout occurred while waiting for the NVM Express Command Packet to execute. - -**/ -EFI_STATUS -EFIAPI -NvmExpressPassThru ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN UINT32 NamespaceId, - IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet, - IN EFI_EVENT Event OPTIONAL - ); - -/** - Used to retrieve the next namespace ID for this NVM Express controller. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNextNamespace() function retrieves the next valid - namespace ID on this NVM Express controller. - - If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the first valid namespace - ID defined on the NVM Express controller is returned in the location pointed to by NamespaceId - and a status of EFI_SUCCESS is returned. - - If on input the value pointed to by NamespaceId is an invalid namespace ID other than 0xFFFFFFFF, - then EFI_INVALID_PARAMETER is returned. - - If on input the value pointed to by NamespaceId is a valid namespace ID, then the next valid - namespace ID on the NVM Express controller is returned in the location pointed to by NamespaceId, - and EFI_SUCCESS is returned. - - If the value pointed to by NamespaceId is the namespace ID of the last namespace on the NVM - Express controller, then EFI_NOT_FOUND is returned. - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in,out] NamespaceId On input, a pointer to a legal NamespaceId for an NVM Express - namespace present on the NVM Express controller. On output, a - pointer to the next NamespaceId of an NVM Express namespace on - an NVM Express controller. An input value of 0xFFFFFFFF retrieves - the first NamespaceId for an NVM Express namespace present on an - NVM Express controller. - - @retval EFI_SUCCESS The Namespace ID of the next Namespace was returned. - @retval EFI_NOT_FOUND There are no more namespaces defined on this controller. - @retval EFI_INVALID_PARAMETER NamespaceId is an invalid value other than 0xFFFFFFFF. - -**/ -EFI_STATUS -EFIAPI -NvmExpressGetNextNamespace ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN OUT UINT32 *NamespaceId - ); - -/** - Used to translate a device path node to a namespace ID. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNamespace() function determines the namespace ID associated with the - namespace described by DevicePath. - - If DevicePath is a device path node type that the NVM Express Pass Thru driver supports, then the NVM Express - Pass Thru driver will attempt to translate the contents DevicePath into a namespace ID. - - If this translation is successful, then that namespace ID is returned in NamespaceId, and EFI_SUCCESS is returned - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] DevicePath A pointer to the device path node that describes an NVM Express namespace on - the NVM Express controller. - @param[out] NamespaceId The NVM Express namespace ID contained in the device path node. - - @retval EFI_SUCCESS DevicePath was successfully translated to NamespaceId. - @retval EFI_INVALID_PARAMETER If DevicePath or NamespaceId are NULL, then EFI_INVALID_PARAMETER is returned. - @retval EFI_UNSUPPORTED If DevicePath is not a device path node type that the NVM Express Pass Thru driver - supports, then EFI_UNSUPPORTED is returned. - @retval EFI_NOT_FOUND If DevicePath is a device path node type that the NVM Express Pass Thru driver - supports, but there is not a valid translation from DevicePath to a namespace ID, - then EFI_NOT_FOUND is returned. -**/ -EFI_STATUS -EFIAPI -NvmExpressGetNamespace ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT UINT32 *NamespaceId - ); - -/** - Used to allocate and build a device path node for an NVM Express namespace on an NVM Express controller. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.BuildDevicePath() function allocates and builds a single device - path node for the NVM Express namespace specified by NamespaceId. - - If the NamespaceId is not valid, then EFI_NOT_FOUND is returned. - - If DevicePath is NULL, then EFI_INVALID_PARAMETER is returned. - - If there are not enough resources to allocate the device path node, then EFI_OUT_OF_RESOURCES is returned. - - Otherwise, DevicePath is allocated with the boot service AllocatePool(), the contents of DevicePath are - initialized to describe the NVM Express namespace specified by NamespaceId, and EFI_SUCCESS is returned. - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be - allocated and built. Caller must set the NamespaceId to zero if the - device path node will contain a valid UUID. - @param[in,out] DevicePath A pointer to a single device path node that describes the NVM Express - namespace specified by NamespaceId. This function is responsible for - allocating the buffer DevicePath with the boot service AllocatePool(). - It is the caller's responsibility to free DevicePath when the caller - is finished with DevicePath. - @retval EFI_SUCCESS The device path node that describes the NVM Express namespace specified - by NamespaceId was allocated and returned in DevicePath. - @retval EFI_NOT_FOUND The NamespaceId is not valid. - @retval EFI_INVALID_PARAMETER DevicePath is NULL. - @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the DevicePath node. - -**/ -EFI_STATUS -EFIAPI -NvmExpressBuildDevicePath ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN UINT32 NamespaceId, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath - ); - -/** - Dump the execution status from a given completion queue entry. - - @param[in] Cq A pointer to the NVME_CQ item. - -**/ -VOID -NvmeDumpStatus ( - IN NVME_CQ *Cq - ); - -/** - Register the shutdown notification through the ResetNotification protocol. - - Register the shutdown notification when mNvmeControllerNumber increased from 0 to 1. -**/ -VOID -NvmeRegisterShutdownNotification ( - VOID - ); - -/** - Unregister the shutdown notification through the ResetNotification protocol. - - Unregister the shutdown notification when mNvmeControllerNumber decreased from 1 to 0. -**/ -VOID -NvmeUnregisterShutdownNotification ( - VOID - ); - -#endif diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressBlockIo.c b/MsvmPkg/NvmExpressDxe/NvmExpressBlockIo.c deleted file mode 100644 index 5d0ae30565..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressBlockIo.c +++ /dev/null @@ -1,1889 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "NvmExpress.h" - -/** - Read some sectors from the device. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data structure. - @param Buffer The buffer used to store the data read from the device. - @param Lba The start block number. - @param Blocks Total block number to be read. - - @retval EFI_SUCCESS Datum are read from the device. - @retval Others Fail to read all the datum. - -**/ -EFI_STATUS -ReadSectors ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - IN UINT64 Buffer, - IN UINT64 Lba, - IN UINT32 Blocks - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - UINT32 Bytes; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - UINT32 BlockSize; - - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - Bytes = Blocks * BlockSize; - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_READ_OPC; - CommandPacket.NvmeCmd->Nsid = Device->NamespaceId; - CommandPacket.TransferBuffer = (VOID *)(UINTN)Buffer; - - CommandPacket.TransferLength = Bytes; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_IO_QUEUE; - - CommandPacket.NvmeCmd->Cdw10 = (UINT32)Lba; - CommandPacket.NvmeCmd->Cdw11 = (UINT32)RShiftU64 (Lba, 32); - CommandPacket.NvmeCmd->Cdw12 = (Blocks - 1) & 0xFFFF; - - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - Device->NamespaceId, - &CommandPacket, - NULL - ); - - return Status; -} - -/** - Write some sectors to the device. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data structure. - @param Buffer The buffer to be written into the device. - @param Lba The start block number. - @param Blocks Total block number to be written. - - @retval EFI_SUCCESS Datum are written into the buffer. - @retval Others Fail to write all the datum. - -**/ -EFI_STATUS -WriteSectors ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - IN UINT64 Buffer, - IN UINT64 Lba, - IN UINT32 Blocks - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - UINT32 Bytes; - UINT32 BlockSize; - - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - Bytes = Blocks * BlockSize; - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_WRITE_OPC; - CommandPacket.NvmeCmd->Nsid = Device->NamespaceId; - CommandPacket.TransferBuffer = (VOID *)(UINTN)Buffer; - - CommandPacket.TransferLength = Bytes; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_IO_QUEUE; - - CommandPacket.NvmeCmd->Cdw10 = (UINT32)Lba; - CommandPacket.NvmeCmd->Cdw11 = (UINT32)RShiftU64 (Lba, 32); - // - // Set Force Unit Access bit (bit 30) to use write-through behaviour - // - CommandPacket.NvmeCmd->Cdw12 = ((Blocks - 1) & 0xFFFF) | BIT30; - - CommandPacket.MetadataBuffer = NULL; - CommandPacket.MetadataLength = 0; - - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - Device->NamespaceId, - &CommandPacket, - NULL - ); - - return Status; -} - -/** - Read some blocks from the device. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data structure. - @param Buffer The buffer used to store the data read from the device. - @param Lba The start block number. - @param Blocks Total block number to be read. - - @retval EFI_SUCCESS Datum are read from the device. - @retval Others Fail to read all the datum. - -**/ -EFI_STATUS -NvmeRead ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - OUT VOID *Buffer, - IN UINT64 Lba, - IN UINTN Blocks - ) -{ - EFI_STATUS Status; - UINT32 BlockSize; - NVME_CONTROLLER_PRIVATE_DATA *Private; - UINT32 MaxTransferBlocks; - UINTN OrginalBlocks; - BOOLEAN IsEmpty; - EFI_TPL OldTpl; - - // - // Wait for the device's asynchronous I/O queue to become empty. - // - while (TRUE) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - IsEmpty = IsListEmpty (&Device->AsyncQueue); - gBS->RestoreTPL (OldTpl); - - if (IsEmpty) { - break; - } - - gBS->Stall (100); - } - - Status = EFI_SUCCESS; - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - OrginalBlocks = Blocks; - - if (Private->ControllerData->Mdts != 0) { - MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize; - } else { - MaxTransferBlocks = 1024; - } - - while (Blocks > 0) { - if (Blocks > MaxTransferBlocks) { - Status = ReadSectors (Device, (UINT64)(UINTN)Buffer, Lba, MaxTransferBlocks); - - Blocks -= MaxTransferBlocks; - Buffer = (VOID *)(UINTN)((UINT64)(UINTN)Buffer + MaxTransferBlocks * BlockSize); - Lba += MaxTransferBlocks; - } else { - Status = ReadSectors (Device, (UINT64)(UINTN)Buffer, Lba, (UINT32)Blocks); - Blocks = 0; - } - - if (EFI_ERROR (Status)) { - break; - } - } - - DEBUG (( - DEBUG_BLKIO, - "%a: Lba = 0x%08Lx, Original = 0x%08Lx, " - "Remaining = 0x%08Lx, BlockSize = 0x%x, Status = %r\n", - __func__, - Lba, - (UINT64)OrginalBlocks, - (UINT64)Blocks, - BlockSize, - Status - )); - - return Status; -} - -/** - Write some blocks to the device. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data structure. - @param Buffer The buffer to be written into the device. - @param Lba The start block number. - @param Blocks Total block number to be written. - - @retval EFI_SUCCESS Datum are written into the buffer. - @retval Others Fail to write all the datum. - -**/ -EFI_STATUS -NvmeWrite ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - IN VOID *Buffer, - IN UINT64 Lba, - IN UINTN Blocks - ) -{ - EFI_STATUS Status; - UINT32 BlockSize; - NVME_CONTROLLER_PRIVATE_DATA *Private; - UINT32 MaxTransferBlocks; - UINTN OrginalBlocks; - BOOLEAN IsEmpty; - EFI_TPL OldTpl; - - // - // Wait for the device's asynchronous I/O queue to become empty. - // - while (TRUE) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - IsEmpty = IsListEmpty (&Device->AsyncQueue); - gBS->RestoreTPL (OldTpl); - - if (IsEmpty) { - break; - } - - gBS->Stall (100); - } - - Status = EFI_SUCCESS; - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - OrginalBlocks = Blocks; - - if (Private->ControllerData->Mdts != 0) { - MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize; - } else { - MaxTransferBlocks = 1024; - } - - while (Blocks > 0) { - if (Blocks > MaxTransferBlocks) { - Status = WriteSectors (Device, (UINT64)(UINTN)Buffer, Lba, MaxTransferBlocks); - - Blocks -= MaxTransferBlocks; - Buffer = (VOID *)(UINTN)((UINT64)(UINTN)Buffer + MaxTransferBlocks * BlockSize); - Lba += MaxTransferBlocks; - } else { - Status = WriteSectors (Device, (UINT64)(UINTN)Buffer, Lba, (UINT32)Blocks); - Blocks = 0; - } - - if (EFI_ERROR (Status)) { - break; - } - } - - DEBUG (( - DEBUG_BLKIO, - "%a: Lba = 0x%08Lx, Original = 0x%08Lx, " - "Remaining = 0x%08Lx, BlockSize = 0x%x, Status = %r\n", - __func__, - Lba, - (UINT64)OrginalBlocks, - (UINT64)Blocks, - BlockSize, - Status - )); - - return Status; -} - -/** - Flushes all modified data to the device. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS Datum are written into the buffer. - @retval Others Fail to write all the datum. - -**/ -EFI_STATUS -NvmeFlush ( - IN NVME_DEVICE_PRIVATE_DATA *Device - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - - Private = Device->Controller; - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_FLUSH_OPC; - CommandPacket.NvmeCmd->Nsid = Device->NamespaceId; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_IO_QUEUE; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - Device->NamespaceId, - &CommandPacket, - NULL - ); - - return Status; -} - -/** - Nonblocking I/O callback funtion when the event is signaled. - - @param[in] Event The Event this notify function registered to. - @param[in] Context Pointer to the context data registered to the - Event. - -**/ -VOID -EFIAPI -AsyncIoCallback ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - NVME_BLKIO2_SUBTASK *Subtask; - NVME_BLKIO2_REQUEST *Request; - NVME_CQ *Completion; - EFI_BLOCK_IO2_TOKEN *Token; - - gBS->CloseEvent (Event); - - Subtask = (NVME_BLKIO2_SUBTASK *)Context; - Completion = (NVME_CQ *)Subtask->CommandPacket->NvmeCompletion; - Request = Subtask->BlockIo2Request; - Token = Request->Token; - - if (Token->TransactionStatus == EFI_SUCCESS) { - // - // If previous subtask already fails, do not check the result of - // subsequent subtasks. - // - if ((Completion->Sct != 0) || (Completion->Sc != 0)) { - Token->TransactionStatus = EFI_DEVICE_ERROR; - - // - // Dump completion entry status for debugging. - // - DEBUG_CODE_BEGIN (); - NvmeDumpStatus (Completion); - DEBUG_CODE_END (); - } - } - - // - // Remove the subtask from the BlockIo2 subtasks list. - // - RemoveEntryList (&Subtask->Link); - - if (IsListEmpty (&Request->SubtasksQueue) && Request->LastSubtaskSubmitted) { - // - // Remove the BlockIo2 request from the device asynchronous queue. - // - RemoveEntryList (&Request->Link); - FreePool (Request); - gBS->SignalEvent (Token->Event); - } - - FreePool (Subtask->CommandPacket->NvmeCmd); - FreePool (Subtask->CommandPacket->NvmeCompletion); - FreePool (Subtask->CommandPacket); - FreePool (Subtask); -} - -/** - Read some sectors from the device in an asynchronous manner. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data - structure. - @param Request The pointer to the NVME_BLKIO2_REQUEST data structure. - @param Buffer The buffer used to store the data read from the device. - @param Lba The start block number. - @param Blocks Total block number to be read. - @param IsLast The last subtask of an asynchronous read request. - - @retval EFI_SUCCESS Asynchronous read request has been queued. - @retval Others Fail to send the asynchronous request. - -**/ -EFI_STATUS -AsyncReadSectors ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - IN NVME_BLKIO2_REQUEST *Request, - IN UINT64 Buffer, - IN UINT64 Lba, - IN UINT32 Blocks, - IN BOOLEAN IsLast - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - UINT32 Bytes; - NVME_BLKIO2_SUBTASK *Subtask; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *CommandPacket; - EFI_NVM_EXPRESS_COMMAND *Command; - EFI_NVM_EXPRESS_COMPLETION *Completion; - EFI_STATUS Status; - UINT32 BlockSize; - EFI_TPL OldTpl; - - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - Bytes = Blocks * BlockSize; - CommandPacket = NULL; - Command = NULL; - Completion = NULL; - - Subtask = AllocateZeroPool (sizeof (NVME_BLKIO2_SUBTASK)); - if (Subtask == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - - Subtask->Signature = NVME_BLKIO2_SUBTASK_SIGNATURE; - Subtask->IsLast = IsLast; - Subtask->NamespaceId = Device->NamespaceId; - Subtask->BlockIo2Request = Request; - - CommandPacket = AllocateZeroPool (sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - if (CommandPacket == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } else { - Subtask->CommandPacket = CommandPacket; - } - - Command = AllocateZeroPool (sizeof (EFI_NVM_EXPRESS_COMMAND)); - if (Command == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - - Completion = AllocateZeroPool (sizeof (EFI_NVM_EXPRESS_COMPLETION)); - if (Completion == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - - // - // Create Event - // - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - Subtask, - &Subtask->Event - ); - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - CommandPacket->NvmeCmd = Command; - CommandPacket->NvmeCompletion = Completion; - - CommandPacket->NvmeCmd->Cdw0.Opcode = NVME_IO_READ_OPC; - CommandPacket->NvmeCmd->Nsid = Device->NamespaceId; - CommandPacket->TransferBuffer = (VOID *)(UINTN)Buffer; - - CommandPacket->TransferLength = Bytes; - CommandPacket->CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket->QueueType = NVME_IO_QUEUE; - - CommandPacket->NvmeCmd->Cdw10 = (UINT32)Lba; - CommandPacket->NvmeCmd->Cdw11 = (UINT32)RShiftU64 (Lba, 32); - CommandPacket->NvmeCmd->Cdw12 = (Blocks - 1) & 0xFFFF; - - CommandPacket->NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID; - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Private->UnsubmittedSubtasks, &Subtask->Link); - Request->UnsubmittedSubtaskNum++; - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; - -ErrorExit: - // - // Resource cleanup if asynchronous read request has not been queued. - // - if (Completion != NULL) { - FreePool (Completion); - } - - if (Command != NULL) { - FreePool (Command); - } - - if (CommandPacket != NULL) { - FreePool (CommandPacket); - } - - if (Subtask != NULL) { - if (Subtask->Event != NULL) { - gBS->CloseEvent (Subtask->Event); - } - - FreePool (Subtask); - } - - return Status; -} - -/** - Write some sectors from the device in an asynchronous manner. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data - structure. - @param Request The pointer to the NVME_BLKIO2_REQUEST data structure. - @param Buffer The buffer used to store the data written to the - device. - @param Lba The start block number. - @param Blocks Total block number to be written. - @param IsLast The last subtask of an asynchronous write request. - - @retval EFI_SUCCESS Asynchronous write request has been queued. - @retval Others Fail to send the asynchronous request. - -**/ -EFI_STATUS -AsyncWriteSectors ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - IN NVME_BLKIO2_REQUEST *Request, - IN UINT64 Buffer, - IN UINT64 Lba, - IN UINT32 Blocks, - IN BOOLEAN IsLast - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - UINT32 Bytes; - NVME_BLKIO2_SUBTASK *Subtask; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *CommandPacket; - EFI_NVM_EXPRESS_COMMAND *Command; - EFI_NVM_EXPRESS_COMPLETION *Completion; - EFI_STATUS Status; - UINT32 BlockSize; - EFI_TPL OldTpl; - - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - Bytes = Blocks * BlockSize; - CommandPacket = NULL; - Command = NULL; - Completion = NULL; - - Subtask = AllocateZeroPool (sizeof (NVME_BLKIO2_SUBTASK)); - if (Subtask == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - - Subtask->Signature = NVME_BLKIO2_SUBTASK_SIGNATURE; - Subtask->IsLast = IsLast; - Subtask->NamespaceId = Device->NamespaceId; - Subtask->BlockIo2Request = Request; - - CommandPacket = AllocateZeroPool (sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - if (CommandPacket == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } else { - Subtask->CommandPacket = CommandPacket; - } - - Command = AllocateZeroPool (sizeof (EFI_NVM_EXPRESS_COMMAND)); - if (Command == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - - Completion = AllocateZeroPool (sizeof (EFI_NVM_EXPRESS_COMPLETION)); - if (Completion == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - - // - // Create Event - // - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - AsyncIoCallback, - Subtask, - &Subtask->Event - ); - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - CommandPacket->NvmeCmd = Command; - CommandPacket->NvmeCompletion = Completion; - - CommandPacket->NvmeCmd->Cdw0.Opcode = NVME_IO_WRITE_OPC; - CommandPacket->NvmeCmd->Nsid = Device->NamespaceId; - CommandPacket->TransferBuffer = (VOID *)(UINTN)Buffer; - - CommandPacket->TransferLength = Bytes; - CommandPacket->CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket->QueueType = NVME_IO_QUEUE; - - CommandPacket->NvmeCmd->Cdw10 = (UINT32)Lba; - CommandPacket->NvmeCmd->Cdw11 = (UINT32)RShiftU64 (Lba, 32); - // - // Set Force Unit Access bit (bit 30) to use write-through behaviour - // - CommandPacket->NvmeCmd->Cdw12 = ((Blocks - 1) & 0xFFFF) | BIT30; - - CommandPacket->NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID; - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Private->UnsubmittedSubtasks, &Subtask->Link); - Request->UnsubmittedSubtaskNum++; - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; - -ErrorExit: - // - // Resource cleanup if asynchronous read request has not been queued. - // - if (Completion != NULL) { - FreePool (Completion); - } - - if (Command != NULL) { - FreePool (Command); - } - - if (CommandPacket != NULL) { - FreePool (CommandPacket); - } - - if (Subtask != NULL) { - if (Subtask->Event != NULL) { - gBS->CloseEvent (Subtask->Event); - } - - FreePool (Subtask); - } - - return Status; -} - -/** - Read some blocks from the device in an asynchronous manner. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data - structure. - @param Buffer The buffer used to store the data read from the device. - @param Lba The start block number. - @param Blocks Total block number to be read. - @param Token A pointer to the token associated with the transaction. - - @retval EFI_SUCCESS Data are read from the device. - @retval Others Fail to read all the data. - -**/ -EFI_STATUS -NvmeAsyncRead ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - OUT VOID *Buffer, - IN UINT64 Lba, - IN UINTN Blocks, - IN EFI_BLOCK_IO2_TOKEN *Token - ) -{ - EFI_STATUS Status; - UINT32 BlockSize; - NVME_CONTROLLER_PRIVATE_DATA *Private; - NVME_BLKIO2_REQUEST *BlkIo2Req; - UINT32 MaxTransferBlocks; - UINTN OrginalBlocks; - BOOLEAN IsEmpty; - EFI_TPL OldTpl; - - Status = EFI_SUCCESS; - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - OrginalBlocks = Blocks; - BlkIo2Req = AllocateZeroPool (sizeof (NVME_BLKIO2_REQUEST)); - if (BlkIo2Req == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - BlkIo2Req->Signature = NVME_BLKIO2_REQUEST_SIGNATURE; - BlkIo2Req->Token = Token; - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Device->AsyncQueue, &BlkIo2Req->Link); - gBS->RestoreTPL (OldTpl); - - InitializeListHead (&BlkIo2Req->SubtasksQueue); - - if (Private->ControllerData->Mdts != 0) { - MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize; - } else { - MaxTransferBlocks = 1024; - } - - while (Blocks > 0) { - if (Blocks > MaxTransferBlocks) { - Status = AsyncReadSectors ( - Device, - BlkIo2Req, - (UINT64)(UINTN)Buffer, - Lba, - MaxTransferBlocks, - FALSE - ); - - Blocks -= MaxTransferBlocks; - Buffer = (VOID *)(UINTN)((UINT64)(UINTN)Buffer + MaxTransferBlocks * BlockSize); - Lba += MaxTransferBlocks; - } else { - Status = AsyncReadSectors ( - Device, - BlkIo2Req, - (UINT64)(UINTN)Buffer, - Lba, - (UINT32)Blocks, - TRUE - ); - - Blocks = 0; - } - - if (EFI_ERROR (Status)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - IsEmpty = IsListEmpty (&BlkIo2Req->SubtasksQueue) && - (BlkIo2Req->UnsubmittedSubtaskNum == 0); - - if (IsEmpty) { - // - // Remove the BlockIo2 request from the device asynchronous queue. - // - RemoveEntryList (&BlkIo2Req->Link); - FreePool (BlkIo2Req); - Status = EFI_DEVICE_ERROR; - } else { - // - // There are previous BlockIo2 subtasks still running, EFI_SUCCESS - // should be returned to make sure that the caller does not free - // resources still using by these requests. - // - Status = EFI_SUCCESS; - Token->TransactionStatus = EFI_DEVICE_ERROR; - BlkIo2Req->LastSubtaskSubmitted = TRUE; - } - - gBS->RestoreTPL (OldTpl); - - break; - } - } - - DEBUG (( - DEBUG_BLKIO, - "%a: Lba = 0x%08Lx, Original = 0x%08Lx, " - "Remaining = 0x%08Lx, BlockSize = 0x%x, Status = %r\n", - __func__, - Lba, - (UINT64)OrginalBlocks, - (UINT64)Blocks, - BlockSize, - Status - )); - - return Status; -} - -/** - Write some blocks from the device in an asynchronous manner. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data - structure. - @param Buffer The buffer used to store the data written to the - device. - @param Lba The start block number. - @param Blocks Total block number to be written. - @param Token A pointer to the token associated with the transaction. - - @retval EFI_SUCCESS Data are written to the device. - @retval Others Fail to write all the data. - -**/ -EFI_STATUS -NvmeAsyncWrite ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - IN VOID *Buffer, - IN UINT64 Lba, - IN UINTN Blocks, - IN EFI_BLOCK_IO2_TOKEN *Token - ) -{ - EFI_STATUS Status; - UINT32 BlockSize; - NVME_CONTROLLER_PRIVATE_DATA *Private; - NVME_BLKIO2_REQUEST *BlkIo2Req; - UINT32 MaxTransferBlocks; - UINTN OrginalBlocks; - BOOLEAN IsEmpty; - EFI_TPL OldTpl; - - Status = EFI_SUCCESS; - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - OrginalBlocks = Blocks; - BlkIo2Req = AllocateZeroPool (sizeof (NVME_BLKIO2_REQUEST)); - if (BlkIo2Req == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - BlkIo2Req->Signature = NVME_BLKIO2_REQUEST_SIGNATURE; - BlkIo2Req->Token = Token; - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Device->AsyncQueue, &BlkIo2Req->Link); - gBS->RestoreTPL (OldTpl); - - InitializeListHead (&BlkIo2Req->SubtasksQueue); - - if (Private->ControllerData->Mdts != 0) { - MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize; - } else { - MaxTransferBlocks = 1024; - } - - while (Blocks > 0) { - if (Blocks > MaxTransferBlocks) { - Status = AsyncWriteSectors ( - Device, - BlkIo2Req, - (UINT64)(UINTN)Buffer, - Lba, - MaxTransferBlocks, - FALSE - ); - - Blocks -= MaxTransferBlocks; - Buffer = (VOID *)(UINTN)((UINT64)(UINTN)Buffer + MaxTransferBlocks * BlockSize); - Lba += MaxTransferBlocks; - } else { - Status = AsyncWriteSectors ( - Device, - BlkIo2Req, - (UINT64)(UINTN)Buffer, - Lba, - (UINT32)Blocks, - TRUE - ); - - Blocks = 0; - } - - if (EFI_ERROR (Status)) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - IsEmpty = IsListEmpty (&BlkIo2Req->SubtasksQueue) && - (BlkIo2Req->UnsubmittedSubtaskNum == 0); - - if (IsEmpty) { - // - // Remove the BlockIo2 request from the device asynchronous queue. - // - RemoveEntryList (&BlkIo2Req->Link); - FreePool (BlkIo2Req); - Status = EFI_DEVICE_ERROR; - } else { - // - // There are previous BlockIo2 subtasks still running, EFI_SUCCESS - // should be returned to make sure that the caller does not free - // resources still using by these requests. - // - Status = EFI_SUCCESS; - Token->TransactionStatus = EFI_DEVICE_ERROR; - BlkIo2Req->LastSubtaskSubmitted = TRUE; - } - - gBS->RestoreTPL (OldTpl); - - break; - } - } - - DEBUG (( - DEBUG_BLKIO, - "%a: Lba = 0x%08Lx, Original = 0x%08Lx, " - "Remaining = 0x%08Lx, BlockSize = 0x%x, Status = %r\n", - __func__, - Lba, - (UINT64)OrginalBlocks, - (UINT64)Blocks, - BlockSize, - Status - )); - - return Status; -} - -/** - Reset the Block Device. - - @param This Indicates a pointer to the calling context. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - EFI_TPL OldTpl; - NVME_CONTROLLER_PRIVATE_DATA *Private; - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // For Nvm Express subsystem, reset block device means reset controller. - // - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - - Private = Device->Controller; - - Status = NvmeControllerReset (Private); // MU_CHANGE - Allocate IO Queue Buffer - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - } - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Read BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId Id of the media, changes every time the media is replaced. - @param Lba The starting Logical Block Address to read from. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN IoAlign; - EFI_TPL OldTpl; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Media = This->Media; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - - Status = NvmeRead (Device, Buffer, Lba, NumberOfBlocks); - - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Write BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId The media ID that the write request is for. - @param Lba The starting logical block address to be written. The caller is - responsible for writing to only legitimate locations. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN IoAlign; - EFI_TPL OldTpl; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Media = This->Media; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - - Status = NvmeWrite (Device, Buffer, Lba, NumberOfBlocks); - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Flush the Block Device. - - @param This Indicates a pointer to the calling context. - - @retval EFI_SUCCESS All outstanding data was written to the device. - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data. - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - EFI_TPL OldTpl; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - - Status = NvmeFlush (Device); - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Reset the block device hardware. - - @param[in] This Indicates a pointer to the calling context. - @param[in] ExtendedVerification Indicates that the driver may perform a more - exhausive verfication operation of the - device during reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoResetEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - EFI_STATUS Status; - NVME_DEVICE_PRIVATE_DATA *Device; - NVME_CONTROLLER_PRIVATE_DATA *Private; - BOOLEAN IsEmpty; - EFI_TPL OldTpl; - - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This); - Private = Device->Controller; - - // - // Wait for the asynchronous PassThru queue to become empty. - // - while (TRUE) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - IsEmpty = IsListEmpty (&Private->AsyncPassThruQueue) && - IsListEmpty (&Private->UnsubmittedSubtasks); - gBS->RestoreTPL (OldTpl); - - if (IsEmpty) { - break; - } - - gBS->Stall (100); - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Status = NvmeControllerReset (Private); // MU_CHANGE - Allocate IO Queue Buffer - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - } - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Read BufferSize bytes from Lba into Buffer. - - This function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. - If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and - non-blocking I/O is being used, the Event associated with this request will - not be signaled. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId Id of the media, changes every time the media is - replaced. - @param[in] Lba The starting Logical Block Address to read from. - @param[in, out] Token A pointer to the token associated with the - transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device - block size. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for either having - implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The read request was queued if Token->Event is - not NULL.The data was read correctly from the - device if the Token->Event is NULL. - @retval EFI_DEVICE_ERROR The device reported an error while performing - the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not on proper - alignment. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoReadBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN IoAlign; - EFI_TPL OldTpl; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Media = This->Media; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - gBS->SignalEvent (Token->Event); - } - - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This); - - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - Status = NvmeAsyncRead (Device, Buffer, Lba, NumberOfBlocks, Token); - } else { - Status = NvmeRead (Device, Buffer, Lba, NumberOfBlocks); - } - - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Write BufferSize bytes from Lba into Buffer. - - This function writes the requested number of blocks to the device. All blocks - are written, or an error is returned.If EFI_DEVICE_ERROR, EFI_NO_MEDIA, - EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is - being used, the Event associated with this request will not be signaled. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the write request is for. - @param[in] Lba The starting logical block address to be written. - The caller is responsible for writing to only - legitimate locations. - @param[in, out] Token A pointer to the token associated with the - transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device - block size. - @param[in] Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The write request was queued if Event is not - NULL. - The data was written correctly to the device if - the Event is NULL. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current - device. - @retval EFI_DEVICE_ERROR The device reported an error while performing - the write. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size - of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not - valid, or the buffer is not on proper - alignment. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoWriteBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN IoAlign; - EFI_TPL OldTpl; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Media = This->Media; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - gBS->SignalEvent (Token->Event); - } - - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This); - - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - Status = NvmeAsyncWrite (Device, Buffer, Lba, NumberOfBlocks, Token); - } else { - Status = NvmeWrite (Device, Buffer, Lba, NumberOfBlocks); - } - - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Flush the Block Device. - - If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED - is returned and non-blocking I/O is being used, the Event associated with - this request will not be signaled. - - @param[in] This Indicates a pointer to the calling context. - @param[in,out] Token A pointer to the token associated with the - transaction. - - @retval EFI_SUCCESS The flush request was queued if Event is not - NULL. - All outstanding data was written correctly to - the device if the Event is NULL. - @retval EFI_DEVICE_ERROR The device reported an error while writting back - the data. - @retval EFI_WRITE_PROTECTED The device cannot be written to. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack - of resources. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoFlushBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN OUT EFI_BLOCK_IO2_TOKEN *Token - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - BOOLEAN IsEmpty; - EFI_TPL OldTpl; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This); - - // - // Wait for the asynchronous I/O queue to become empty. - // - while (TRUE) { - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - IsEmpty = IsListEmpty (&Device->AsyncQueue); - gBS->RestoreTPL (OldTpl); - - if (IsEmpty) { - break; - } - - gBS->Stall (100); - } - - // - // Signal caller event - // - if ((Token != NULL) && (Token->Event != NULL)) { - Token->TransactionStatus = EFI_SUCCESS; - gBS->SignalEvent (Token->Event); - } - - return EFI_SUCCESS; -} - -/** - Trust transfer data from/to NVMe device. - - This function performs one NVMe transaction to do a trust transfer from/to NVMe device. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Buffer The pointer to the current transaction buffer. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param TransferLength The block number or sector count of the transfer. - @param IsTrustSend Indicates whether it is a trust send operation or not. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param TransferLengthOut A pointer to a buffer to store the size in bytes of the data - written to the buffer. Ignore it when IsTrustSend is TRUE. - - @retval EFI_SUCCESS The data transfer is complete successfully. - @return others Some error occurs when transferring data. - -**/ -EFI_STATUS -TrustTransferNvmeDevice ( - IN OUT NVME_CONTROLLER_PRIVATE_DATA *Private, - IN OUT VOID *Buffer, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN TransferLength, - IN BOOLEAN IsTrustSend, - IN UINT64 Timeout, - OUT UINTN *TransferLengthOut - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - UINT16 SpecificData; - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - // - // Change Endianness of SecurityProtocolSpecificData - // - SpecificData = (((SecurityProtocolSpecificData << 8) & 0xFF00) | (SecurityProtocolSpecificData >> 8)); - - if (IsTrustSend) { - Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_SEND_CMD; - CommandPacket.TransferBuffer = Buffer; - CommandPacket.TransferLength = (UINT32)TransferLength; - CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SpecificData << 8)); - CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength; - } else { - Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_RECEIVE_CMD; - CommandPacket.TransferBuffer = Buffer; - CommandPacket.TransferLength = (UINT32)TransferLength; - CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SpecificData << 8)); - CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength; - } - - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID; - CommandPacket.NvmeCmd->Nsid = NVME_CONTROLLER_ID; - CommandPacket.CommandTimeout = Timeout; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - NVME_CONTROLLER_ID, - &CommandPacket, - NULL - ); - - if (!IsTrustSend) { - if (EFI_ERROR (Status)) { - *TransferLengthOut = 0; - } else { - *TransferLengthOut = (UINTN)TransferLength; - } - } - - return Status; -} - -/** - Send a security protocol command to a device that receives data and/or the result - of one or more commands sent by SendData. - - The ReceiveData function sends a security protocol command to the given MediaId. - The security protocol command sent is defined by SecurityProtocolId and contains - the security protocol specific data SecurityProtocolSpecificData. The function - returns the data from the security protocol command in PayloadBuffer. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL IN command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. - - If the PayloadBufferSize is zero, the security protocol command is sent using the - Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBufferSize is too small to store the available data from the security - protocol command, the function shall copy PayloadBufferSize bytes into the - PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL. - - If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero, - the function shall return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function shall - return EFI_UNSUPPORTED. If there is no media in the device, the function returns - EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device, - the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall - return EFI_SUCCESS. If the security protocol command completes with an error, the - function shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. If there is no - block IO protocol supported by the physical device, the - value of MediaId is undefined. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. The caller is responsible for having - either implicit or explicit ownership of the buffer. - @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the - data written to the payload data buffer. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available - data from the device. The PayloadBuffer contains the truncated data. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and - PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -NvmeStorageSecurityReceiveData ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - OUT VOID *PayloadBuffer, - OUT UINTN *PayloadTransferSize - ) -{ - EFI_STATUS Status; - NVME_DEVICE_PRIVATE_DATA *Device; - - Status = EFI_SUCCESS; - - if ((PayloadBuffer == NULL) || (PayloadTransferSize == NULL) || (PayloadBufferSize == 0)) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY (This); - - if (MediaId != Device->BlockIo.Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (!Device->BlockIo.Media->MediaPresent) { - return EFI_NO_MEDIA; - } - - Status = TrustTransferNvmeDevice ( - Device->Controller, - PayloadBuffer, - SecurityProtocolId, - SecurityProtocolSpecificData, - PayloadBufferSize, - FALSE, - Timeout, - PayloadTransferSize - ); - - return Status; -} - -/** - Send a security protocol command to a device. - - The SendData function sends a security protocol command containing the payload - PayloadBuffer to the given MediaId. The security protocol command sent is - defined by SecurityProtocolId and contains the security protocol specific data - SecurityProtocolSpecificData. If the underlying protocol command requires a - specific padding for the command payload, the SendData function shall add padding - bytes to the command payload to satisfy the padding requirements. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL OUT command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. If the PayloadBufferSize is zero, the security protocol command is - sent using the Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall - return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function - shall return EFI_UNSUPPORTED. If there is no media in the device, the function - returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the - device, the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall return - EFI_SUCCESS. If the security protocol command completes with an error, the function - shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. If there is no - block IO protocol supported by the physical device, the - value of MediaId is undefined. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the send data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -NvmeStorageSecuritySendData ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - IN VOID *PayloadBuffer - ) -{ - EFI_STATUS Status; - NVME_DEVICE_PRIVATE_DATA *Device; - - Status = EFI_SUCCESS; - - if ((PayloadBuffer == NULL) && (PayloadBufferSize != 0)) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY (This); - - if (MediaId != Device->BlockIo.Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (!Device->BlockIo.Media->MediaPresent) { - return EFI_NO_MEDIA; - } - - Status = TrustTransferNvmeDevice ( - Device->Controller, - PayloadBuffer, - SecurityProtocolId, - SecurityProtocolSpecificData, - PayloadBufferSize, - TRUE, - Timeout, - NULL - ); - - return Status; -} diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressBlockIo.h b/MsvmPkg/NvmExpressDxe/NvmExpressBlockIo.h deleted file mode 100644 index 5547e057e7..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressBlockIo.h +++ /dev/null @@ -1,415 +0,0 @@ -/** @file - Header file for EFI_BLOCK_IO_PROTOCOL interface. - -Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _EFI_NVME_BLOCKIO_H_ -#define _EFI_NVME_BLOCKIO_H_ - -/** - Reset the Block Device. - - @param This Indicates a pointer to the calling context. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -/** - Read BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId Id of the media, changes every time the media is replaced. - @param Lba The starting Logical Block Address to read from - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Write BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId The media ID that the write request is for. - @param Lba The starting logical block address to be written. The caller is - responsible for writing to only legitimate locations. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Flush the Block Device. - - @param This Indicates a pointer to the calling context. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ); - -/** - Reset the block device hardware. - - @param[in] This Indicates a pointer to the calling context. - @param[in] ExtendedVerification Indicates that the driver may perform a more - exhausive verfication operation of the - device during reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoResetEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -/** - Read BufferSize bytes from Lba into Buffer. - - This function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. - If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and - non-blocking I/O is being used, the Event associated with this request will - not be signaled. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId Id of the media, changes every time the media is - replaced. - @param[in] Lba The starting Logical Block Address to read from. - @param[in, out] Token A pointer to the token associated with the - transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device - block size. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for either having - implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The read request was queued if Token->Event is - not NULL.The data was read correctly from the - device if the Token->Event is NULL. - @retval EFI_DEVICE_ERROR The device reported an error while performing - the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not on proper - alignment. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoReadBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Write BufferSize bytes from Lba into Buffer. - - This function writes the requested number of blocks to the device. All blocks - are written, or an error is returned.If EFI_DEVICE_ERROR, EFI_NO_MEDIA, - EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is - being used, the Event associated with this request will not be signaled. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the write request is for. - @param[in] Lba The starting logical block address to be written. - The caller is responsible for writing to only - legitimate locations. - @param[in, out] Token A pointer to the token associated with the - transaction. - @param[in] BufferSize Size of Buffer, must be a multiple of device - block size. - @param[in] Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The write request was queued if Event is not - NULL. - The data was written correctly to the device if - the Event is NULL. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current - device. - @retval EFI_DEVICE_ERROR The device reported an error while performing - the write. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size - of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not - valid, or the buffer is not on proper - alignment. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoWriteBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Flush the Block Device. - - If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED - is returned and non-blocking I/O is being used, the Event associated with - this request will not be signaled. - - @param[in] This Indicates a pointer to the calling context. - @param[in,out] Token A pointer to the token associated with the - transaction. - - @retval EFI_SUCCESS The flush request was queued if Event is not - NULL. - All outstanding data was written correctly to - the device if the Event is NULL. - @retval EFI_DEVICE_ERROR The device reported an error while writting back - the data. - @retval EFI_WRITE_PROTECTED The device cannot be written to. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack - of resources. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoFlushBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN OUT EFI_BLOCK_IO2_TOKEN *Token - ); - -/** - Send a security protocol command to a device that receives data and/or the result - of one or more commands sent by SendData. - - The ReceiveData function sends a security protocol command to the given MediaId. - The security protocol command sent is defined by SecurityProtocolId and contains - the security protocol specific data SecurityProtocolSpecificData. The function - returns the data from the security protocol command in PayloadBuffer. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL IN command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. - - If the PayloadBufferSize is zero, the security protocol command is sent using the - Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBufferSize is too small to store the available data from the security - protocol command, the function shall copy PayloadBufferSize bytes into the - PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL. - - If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero, - the function shall return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function shall - return EFI_UNSUPPORTED. If there is no media in the device, the function returns - EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device, - the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall - return EFI_SUCCESS. If the security protocol command completes with an error, the - function shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. If there is no - block IO protocol supported by the physical device, the - value of MediaId is undefined. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. The caller is responsible for having - either implicit or explicit ownership of the buffer. - @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the - data written to the payload data buffer. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available - data from the device. The PayloadBuffer contains the truncated data. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and - PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -NvmeStorageSecurityReceiveData ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - OUT VOID *PayloadBuffer, - OUT UINTN *PayloadTransferSize - ); - -/** - Send a security protocol command to a device. - - The SendData function sends a security protocol command containing the payload - PayloadBuffer to the given MediaId. The security protocol command sent is - defined by SecurityProtocolId and contains the security protocol specific data - SecurityProtocolSpecificData. If the underlying protocol command requires a - specific padding for the command payload, the SendData function shall add padding - bytes to the command payload to satisfy the padding requirements. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL OUT command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. If the PayloadBufferSize is zero, the security protocol command is - sent using the Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall - return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function - shall return EFI_UNSUPPORTED. If there is no media in the device, the function - returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the - device, the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall return - EFI_SUCCESS. If the security protocol command completes with an error, the function - shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. If there is no - block IO protocol supported by the physical device, the - value of MediaId is undefined. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -NvmeStorageSecuritySendData ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - IN VOID *PayloadBuffer - ); - -#endif diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressBounce.c b/MsvmPkg/NvmExpressDxe/NvmExpressBounce.c deleted file mode 100644 index 155b23a488..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressBounce.c +++ /dev/null @@ -1,623 +0,0 @@ -/** @file - Bounce buffer routines for NVMe device - - Copyright (c) Microsoft Corporation. - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "NvmExpress.h" -#include "NvmExpressBounce.h" - -EFI_HV_IVM_PROTOCOL *mHvIvm; -UINTN mSharedGpaBoundary; -UINT64 mCanonicalizationMask; - -/** - Return true if NVMe should use bounce buffering. - - @param None. - - @returns TRUE if bounce buffering should be used. -**/ -EFI_STATUS -NvmExpressInitializeBounce( - VOID - ) -{ - mSharedGpaBoundary = (UINTN)PcdGet64(PcdIsolationSharedGpaBoundary); - mCanonicalizationMask = PcdGet64(PcdIsolationSharedGpaCanonicalizationBitmask); - return gBS->LocateProtocol(&gEfiHvIvmProtocolGuid, NULL, (VOID **)&mHvIvm); -} - -/** - Return true if NVMe should use bounce buffering. - - @param None. - - @returns TRUE if bounce buffering should be used. -**/ -BOOLEAN -NvmExpressIsBounceActive( - VOID - ) -{ - return IsIsolated(); -} - - -/** - Allocate a large block of memory from EFI for I/O. Mark the memory as host- - visible. Allocate tracking structures to sub-allocate the block into - individual pages. - - @param[in] Private Pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param[in] BlockByteCount Number of bytes to allocate for I/O. Must be a multiple of EFI_PAGE_SIZE. - - @retval EFI_SUCCESS - @retval EFI_OUT_OF_RESOURCES Memory allocation failures or other failures from hypervisor - page visibility call. -**/ -EFI_STATUS -NvmExpressAllocateBounceBlock( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT32 BlockByteCount - ) -{ - EFI_STATUS status = EFI_INVALID_PARAMETER; - UINT32 pageCount = 0; - UINT32 i = 0; - PNVME_BOUNCE_BLOCK bounceBlock = NULL; - UINT8* nextVa; - UINT64 nextPa; - - DEBUG((EFI_D_VERBOSE, - "%a(%d) Context=%p ByteCount=0x%x\n", - __func__, - __LINE__, - Private, - BlockByteCount)); - - if (BlockByteCount % EFI_PAGE_SIZE) { - status = EFI_INVALID_PARAMETER; - goto Cleanup; - } - - pageCount = BlockByteCount / EFI_PAGE_SIZE; - - bounceBlock = AllocatePool(sizeof(*bounceBlock)); - if (bounceBlock == NULL) { - status = EFI_OUT_OF_RESOURCES; - goto Cleanup; - } - - ZeroMem(bounceBlock, sizeof(*bounceBlock)); - - // Allocate the bounce page memory - - bounceBlock->BlockBase = AllocatePages(pageCount); - if (bounceBlock->BlockBase == NULL) { - status = EFI_OUT_OF_RESOURCES; - goto Cleanup; - } - - bounceBlock->BlockPageCount = pageCount; - ZeroMem(bounceBlock->BlockBase, pageCount * EFI_PAGE_SIZE); - - // Allocate the tracking structures as one - bounceBlock->BouncePageStructureBase = AllocatePool(pageCount * sizeof(NVME_BOUNCE_PAGE)); - if (bounceBlock->BouncePageStructureBase == NULL) { - status = EFI_OUT_OF_RESOURCES; - goto Cleanup; - } - - bounceBlock->FreePageListHead = bounceBlock->BouncePageStructureBase; - nextVa = bounceBlock->BlockBase; - nextPa = (UINT64)nextVa; - - // - // Make these pages visible to the host - // - - if (IsIsolated()) { - status = mHvIvm->MakeAddressRangeHostVisible(mHvIvm, - HV_MAP_GPA_READABLE | HV_MAP_GPA_WRITABLE, - bounceBlock->BlockBase, - pageCount * EFI_PAGE_SIZE, - FALSE, - &bounceBlock->ProtectionHandle); - - if (EFI_ERROR(status)) { - goto Cleanup; - } - - // - // Adjust the address above the shared GPA boundary if required. - // - nextPa += mSharedGpaBoundary; - - // - // Canonicalize the VA. - // - nextVa = (VOID *)(mCanonicalizationMask | nextPa); - bounceBlock->IsHostVisible = TRUE; - } - - for (i = 0; i < pageCount; i++) { - if (i == (pageCount - 1)) { - bounceBlock->BouncePageStructureBase[i].NextBouncePage = NULL; - } else { - bounceBlock->BouncePageStructureBase[i].NextBouncePage = - &bounceBlock->BouncePageStructureBase[i + 1]; - } - - bounceBlock->BouncePageStructureBase[i].BounceBlock = bounceBlock; - bounceBlock->BouncePageStructureBase[i].PageVA = nextVa; - bounceBlock->BouncePageStructureBase[i].HostVisiblePA = nextPa; - nextVa += EFI_PAGE_SIZE; - nextPa += EFI_PAGE_SIZE; - } - - InsertTailList(&Private->BounceBlockListHead, &bounceBlock->BlockListEntry); - status = EFI_SUCCESS; - - Cleanup: - DEBUG((EFI_D_INFO, - "%a (%d) Context=%p bounceBlock=%p status=0x%x\n", - __func__, - __LINE__, - Private, - bounceBlock, - status)); - - if (EFI_ERROR(status)) { - if (bounceBlock) { - NvmExpressFreeBounceBlock(bounceBlock); - bounceBlock = NULL; - } - } - return status; -} - -/** - Free the block of memory allocated for I/O. Marks the memory as not host-visible. - - @param[in] Block Bounce block that needs to be freed. - -**/ -VOID -NvmExpressFreeBounceBlock( - IN PNVME_BOUNCE_BLOCK Block - ) -{ - if (Block->IsHostVisible) { - mHvIvm->MakeAddressRangeNotHostVisible(mHvIvm, &Block->ProtectionHandle); - } - - if (Block->BouncePageStructureBase) { - FreePool(Block->BouncePageStructureBase); - Block->BouncePageStructureBase = NULL; - } - - if (Block->BlockBase) { - FreePages(Block->BlockBase, Block->BlockPageCount); - Block->BlockBase = NULL; - Block->BlockPageCount = 0; - } - - FreePool(Block); -} - -/** - Free all of the large blocks of memory allocated for I/O. Marks the memory - as not host-visible. Frees the associated tracking structures. - - @param[in] Private Pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - -**/ -VOID -NvmExpressFreeAllBounceBlocks( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) - -{ - PNVME_BOUNCE_BLOCK block; - LIST_ENTRY* entry; - - while (!IsListEmpty(&Private->BounceBlockListHead)) { - - entry = GetFirstNode(&Private->BounceBlockListHead); - RemoveEntryList(entry); - - block = BASE_CR(entry, NVME_BOUNCE_BLOCK, BlockListEntry); - - DEBUG((EFI_D_WARN, - "%a (%d) Context=%p block=%p IsHostVis=%d InUsePageCount=%d BlockBase=%p PageCount=0x%x\n", - __func__, - __LINE__, - Private, - block, - block->IsHostVisible, - block->InUsePageCount, - block->BlockBase, - block->BlockPageCount)); - - NvmExpressFreeBounceBlock(block); - block = NULL; - } -} - -/** - Remove 'PageCount' pre-allocated NVME_BOUNCE_PAGE structures from the - NVME_CONTROLLER_PRIVATE_DATA context and return them in a linked-list. - These PAGE structures will be used in an I/O. - - @param[in] Private Pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param[in] PageCount Number of NVME_BOUNCE_PAGE structures to acquire from the - NVME_CONTROLLER_PRIVATE_DATA context structure and return to - the caller. - - @retval Linked list of NVME_BOUNCE_PAGE structures or NULL on failure. -**/ -PNVME_BOUNCE_PAGE -NvmExpressAcquireBouncePages( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT32 PageCount - ) -{ - PNVME_BOUNCE_PAGE listHead = NULL; - UINT32 pagesToGo = PageCount; - EFI_STATUS status; - - DEBUG((EFI_D_VERBOSE, - "%a(%d) Context=%p PageCount=%d\n", - __func__, - __LINE__, - Private, - PageCount)); - -Retry: - if (!IsListEmpty(&Private->BounceBlockListHead)) { - LIST_ENTRY* blockListEntry; - - for (blockListEntry = Private->BounceBlockListHead.ForwardLink; - blockListEntry != &Private->BounceBlockListHead; - blockListEntry = blockListEntry->ForwardLink) { - - PNVME_BOUNCE_BLOCK bounceBlock; - bounceBlock = BASE_CR(blockListEntry, NVME_BOUNCE_BLOCK, BlockListEntry); - - while (bounceBlock->FreePageListHead && pagesToGo) { - - PNVME_BOUNCE_PAGE bouncePage; - - bouncePage = bounceBlock->FreePageListHead; - bounceBlock->FreePageListHead = bouncePage->NextBouncePage; - - bouncePage->NextBouncePage = listHead; - listHead = bouncePage; - - bounceBlock->InUsePageCount++; - - pagesToGo--; - } - - if (pagesToGo == 0) { - break; - } - } - - if (pagesToGo) { - UINT32 allocSize = MAX(pagesToGo * EFI_PAGE_SIZE, 32 * EFI_PAGE_SIZE); - - status = NvmExpressAllocateBounceBlock(Private, allocSize); - if (EFI_ERROR(status)) { - DEBUG((EFI_D_WARN, - "%a(%d) Context=%p Bounce block allocation failure\n", - __func__, - __LINE__, - Private)); - goto Exit; - } - goto Retry; - } - } - -Exit: - if (pagesToGo) { - // failed - NvmExpressReleaseBouncePages(Private, listHead); - - DEBUG((EFI_D_WARN, - "%a(%d) Context=%p PageCount=%d Returning=NULL\n", - __func__, - __LINE__, - Private, - PageCount)); - } else { - DEBUG((EFI_D_VERBOSE, - "%a(%d) Context=%p PageCount=%d Returning=%p\n", - __func__, - __LINE__, - Private, - PageCount, - listHead)); - } - return listHead; -} - -/** - Return NVME_BOUNCE_PAGES from a linked list to their 'home' NVME_BOUNCE_BLOCK lists. - Effectively frees these temporary pages for use by another I/O. - - @param[in] Private Pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param[in] BounceListHead Linked list of one more NVME_BOUNCE_PAGE structures. - -**/ -VOID -NvmExpressReleaseBouncePages( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN OUT PNVME_BOUNCE_PAGE BounceListHead - ) -{ - PNVME_BOUNCE_PAGE page; - UINT32 count = 0; - - while (BounceListHead) { - page = BounceListHead; - BounceListHead = BounceListHead->NextBouncePage; - - page->BounceBlock->InUsePageCount--; - count++; - - page->NextBouncePage = page->BounceBlock->FreePageListHead; - page->BounceBlock->FreePageListHead = page; - } - - DEBUG((EFI_D_VERBOSE, - "%a(%d) Context=%p released PageCount=%d\n", - __func__, - __LINE__, - Private, - count)); - - BounceListHead = NULL; -} - -/** - Copy between the memory pages in the bounce buffers and the client's - buffer respecting the page offsets of the client's buffer. This function - will zero the partial pages at the beginning and end of the BouncePageList. - - @param[in] ExternalBuffer The EFI client's data buffer. Can start at any - @param[in] BufferSize Size of EFI client's data buffer. - @param[in] BouncePageList List of bounce pages (shared with host) - @param[in] CopyToBounce If TRUE, copy from ExternalBuffer into the BouncePageList. - If FALSE, copy from the BouncePageList into ExternalBuffer. - -**/ -VOID -NvmExpressCopyBouncePagesToExternalBuffer( - IN VOID * ExternalBuffer, - IN UINT32 BufferSize, - IN PNVME_BOUNCE_PAGE BouncePageList, - IN BOOLEAN CopyToBounce - ) -{ - UINT64 pageOffset; - PNVME_BOUNCE_PAGE bouncePage; - UINT8* bounceBuffer; - UINT8* bounceBufferEnd; - UINT8* extBuffer; - UINT32 transferToGo; - UINT32 copySize; - - DEBUG((EFI_D_INFO, - "%a(%d) ExternalBuffer.Buffer=%p Size=0x%x BouncePageList=%p CopyToBounce=%d\n", - __func__, - __LINE__, - ExternalBuffer, - BufferSize, - BouncePageList, - CopyToBounce)); - - ASSERT (BouncePageList); - - bouncePage = BouncePageList; - pageOffset = (UINT64)ExternalBuffer % EFI_PAGE_SIZE; - - extBuffer = ExternalBuffer; - transferToGo = BufferSize; - - while (transferToGo) { - ASSERT(bouncePage); - - bounceBuffer = (UINT8*)bouncePage->PageVA; - - // Zero any unused space in buffer we are sharing with the host. - if (CopyToBounce && pageOffset) { - DEBUG((EFI_D_VERBOSE, - "%a(%d) Zero %p size=0x%x\n", - __func__, - __LINE__, - bouncePage->PageVA, - pageOffset)); - ZeroMem(bouncePage->PageVA, pageOffset); - } - - // First page offset - bounceBuffer += pageOffset; - copySize = EFI_PAGE_SIZE - (UINT32)pageOffset; - pageOffset = 0; // no more offsets - - copySize = MIN(copySize, transferToGo); - bounceBufferEnd = bounceBuffer + copySize; - - if (CopyToBounce) { - DEBUG((EFI_D_VERBOSE, - "%a(%d) CopyToBounce dst=%p src=%p size=0x%x\n", - __func__, - __LINE__, - bounceBuffer, - extBuffer, - copySize)); - - CopyMem(bounceBuffer, extBuffer, copySize); - } else { - DEBUG((EFI_D_VERBOSE, - "%a(%d) CopyToExtBuffer dst=%p src=%p size=0x%x\n", - __func__, - __LINE__, - extBuffer, - bounceBuffer, - copySize)); - - CopyMem(extBuffer, bounceBuffer, copySize); - } - - transferToGo -= copySize; - extBuffer += copySize; - - // Zero any unused space in buffer we are sharing with the host. - if (transferToGo == 0 && - CopyToBounce && - ((UINT64)bounceBuffer % EFI_PAGE_SIZE)) { - UINT32 endOffset = (UINT64)bounceBufferEnd % EFI_PAGE_SIZE; - UINT32 zeroSize = EFI_PAGE_SIZE - endOffset; - - DEBUG((EFI_D_VERBOSE, - "%a(%d) Zero %p size=0x%x (from offset=0x%x)\n", - __func__, - __LINE__, - bounceBufferEnd, - zeroSize, - endOffset)); - - ZeroMem(bounceBufferEnd, zeroSize); - } - bouncePage = bouncePage->NextBouncePage; - } - - ASSERT(bouncePage == NULL); // should be all done -} - -/** - Zero initialize host-visible bounce page list. - - @param[in] BouncePageList List of bounce pages (shared with host). - -**/ -VOID -NvmExpressZeroBouncePageList( - IN PNVME_BOUNCE_PAGE BouncePageList - ) -{ - PNVME_BOUNCE_PAGE bouncePage = BouncePageList; - UINT32 pageCount = 0; - - while (bouncePage) { - ZeroMem(bouncePage->PageVA, EFI_PAGE_SIZE); - bouncePage = bouncePage->NextBouncePage; - pageCount++; - } - DEBUG((EFI_D_VERBOSE, "%a(%d) BouncePageList=%p zeroed %d pages\n", - __func__, - __LINE__, - BouncePageList, - pageCount)); -} - - -// -// Page visibility -// - -UINTN -NvmExpressGetSharedPa( - VOID* Address - ) -/** - Given an address, which may be either a VA or a PA, removes any - canonicalization bits and returns the shared GPA corresponding to the - address. - - @param Address Input address. - - @returns Shared GPA. - -**/ -{ - UINTN addr; - - addr = (UINTN)Address; - addr &= ~mCanonicalizationMask; - if (addr < mSharedGpaBoundary) - { - addr += mSharedGpaBoundary; - } - - return addr; -} - -VOID* -NvmExpressGetSharedVa( - VOID* Address - ) -/** - Given an address, which may be either a VA or a PA, returns a canonicalized - pointer pointing to the shared GPA alias. - - @param Address Input address. - - @returns Shared VA pointer. - -**/ -{ - return (VOID*)(NvmExpressGetSharedPa(Address) | mCanonicalizationMask); -} - -EFI_STATUS -NvmExpressMakeAddressRangeShared( - IN OUT NVME_HOST_VISIBILITY_CONTEXT *HostVisibilityContext, - IN OUT VOID *BaseAddress, - IN UINT32 ByteCount - ) -{ - ASSERT(IsIsolated()); - - EFI_STATUS status = mHvIvm->MakeAddressRangeHostVisible(mHvIvm, - HV_MAP_GPA_READABLE | HV_MAP_GPA_WRITABLE, - BaseAddress, - ByteCount, - FALSE, - &HostVisibilityContext->RangeProtectionHandle); - - if (EFI_ERROR(status)) - { - return status; - } - - // - // Adjust the address above the shared GPA boundary. - // - BaseAddress = (UINT8 *)((UINTN)BaseAddress + mSharedGpaBoundary); - - return EFI_SUCCESS; -} - - -VOID -NvmExpressMakeAddressRangePrivate( - IN NVME_HOST_VISIBILITY_CONTEXT *HostVisibilityContext, - IN OUT VOID *AddressRange - ) -{ - ASSERT(IsIsolated()); - - mHvIvm->MakeAddressRangeNotHostVisible(mHvIvm, &HostVisibilityContext->RangeProtectionHandle); - - AddressRange = (VOID *)((UINT64)AddressRange & ~mCanonicalizationMask); - if ((UINTN)AddressRange >= mSharedGpaBoundary) { - AddressRange = (VOID *)((UINTN)AddressRange - mSharedGpaBoundary); - } -} diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressBounce.h b/MsvmPkg/NvmExpressDxe/NvmExpressBounce.h deleted file mode 100644 index 224c4bc90b..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressBounce.h +++ /dev/null @@ -1,205 +0,0 @@ -/** @file - Bounce buffer routines for NVMe device - - Copyright (c) Microsoft Corporation. - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#pragma once - -#include - -#include - -#include "NvmExpress.h" - -// -// Nvme bounce buffer support. -// - -#define NVME_BOUNCE_BLOCK_SIZE (32 * EFI_PAGE_SIZE) - -typedef struct _NVME_BOUNCE_BLOCK -{ - LIST_ENTRY BlockListEntry; - - struct _NVME_BOUNCE_PAGE *FreePageListHead; - - UINT32 InUsePageCount; - BOOLEAN IsHostVisible; - - VOID * BlockBase; - UINT32 BlockPageCount; - EFI_HV_PROTECTION_HANDLE ProtectionHandle; - - // Allocate associated _NVME_BOUNCE_PAGE as a large block - struct _NVME_BOUNCE_PAGE *BouncePageStructureBase; -} NVME_BOUNCE_BLOCK, *PNVME_BOUNCE_BLOCK; - -// -// NVME_BOUNCE_PAGE - represents one guest physical page of a block. -// Units of pages are allocated to a vmbus packet as required and -// returned to the 'block pool' when not in use. -// -typedef struct _NVME_BOUNCE_PAGE -{ - struct _NVME_BOUNCE_PAGE* NextBouncePage; - struct _NVME_BOUNCE_BLOCK* BounceBlock; - VOID * PageVA; - UINT64 HostVisiblePA; -} NVME_BOUNCE_PAGE, *PNVME_BOUNCE_PAGE; - -typedef struct _NVME_PAGE_VISIBILITY_CONTEXT -{ - EFI_HV_PROTECTION_HANDLE RangeProtectionHandle; -} NVME_HOST_VISIBILITY_CONTEXT; - - -EFI_STATUS -NvmExpressInitializeBounce( - VOID - ); - -/** - Return true if NVMe should use bounce buffering. - - @param None. - - @returns TRUE if bounce buffering should be used. -**/ -BOOLEAN -NvmExpressIsBounceActive( - VOID - ); - -/** - Allocate a large block of memory from EFI for I/O. Mark the memory as host- - visible. Allocate tracking structures to sub-allocate the block into - individual pages. - - @param[in] Private Pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param[in] BlockByteCount Number of bytes to allocate for I/O. Must be a multiple of EFI_PAGE_SIZE. - - @retval EFI_SUCCESS - @retval EFI_OUT_OF_RESOURCES Memory allocation failures or other failures from hypervisor - page visibility call. -**/ -EFI_STATUS -NvmExpressAllocateBounceBlock( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT32 BlockByteCount - ); - -/** - Free the block of memory allocated for I/O. Marks the memory as not host-visible. - - @param[in] Block Bounce block that needs to be freed. - -**/ -VOID -NvmExpressFreeBounceBlock( - IN PNVME_BOUNCE_BLOCK Block - ); - -/** - Free all of the large blocks of memory allocated for I/O. Marks the memory - as not host-visible. Frees the associated tracking structures. - - @param[in] Private Pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - -**/ -VOID -NvmExpressFreeAllBounceBlocks( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ); - -/** - Remove 'PageCount' pre-allocated NVME_BOUNCE_PAGE structures from the - NVME_CONTROLLER_PRIVATE_DATA context and return them in a linked-list. - These PAGE structures will be used in an I/O. - - @param[in] Private Pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param[in] PageCount Number of NVME_BOUNCE_PAGE structures to acquire from the - NVME_CONTROLLER_PRIVATE_DATA context structure and return to - the caller. - - @retval Linked list of NVME_BOUNCE_PAGE structures or NULL on failure. -**/ -PNVME_BOUNCE_PAGE -NvmExpressAcquireBouncePages( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT32 PageCount - ); - -/** - Return NVME_BOUNCE_PAGES from a linked list to their 'home' NVME_BOUNCE_BLOCK lists. - Effectively frees these temporary pages for use by another I/O. - - @param[in] Private Pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param[in] BounceListHead Linked list of one more NVME_BOUNCE_PAGE structures. - -**/ -VOID -NvmExpressReleaseBouncePages( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN OUT PNVME_BOUNCE_PAGE BounceListHead - ); - -/** - Copy between the memory pages in the bounce buffers and the client's - buffer respecting the page offsets of the client's buffer. This function - will zero the partial pages at the beginning and end of the BouncePageList. - - @param[in] ExternalBuffer The EFI client's data buffer. Can start at any - @param[in] BufferSize Size of EFI client's data buffer. - @param[in] BouncePageList List of bounce pages (shared with host) - @param[in] CopyToBounce If TRUE, copy from ExternalBuffer into the BouncePageList. - If FALSE, copy from the BouncePageList into ExternalBuffer. - -**/ -VOID -NvmExpressCopyBouncePagesToExternalBuffer( - IN VOID * ExternalBuffer, - IN UINT32 BufferSize, - IN PNVME_BOUNCE_PAGE BouncePageList, - IN BOOLEAN CopyToBounce - ); - -/** - Zero initialize host-visible bounce page list. - - @param[in] BouncePageList List of bounce pages (shared with host). - -**/ -VOID -NvmExpressZeroBouncePageList( - IN PNVME_BOUNCE_PAGE BouncePageList - ); - - -// -// Page visibility -// -UINTN -NvmExpressGetSharedPa( - VOID* Address - ); - -VOID* -NvmExpressGetSharedVa( - VOID* Address - ); - -EFI_STATUS -NvmExpressMakeAddressRangeShared( - IN OUT NVME_HOST_VISIBILITY_CONTEXT *HostVisibilityContext, - IN OUT VOID *BaseAddress, - IN UINT32 ByteCount - ); - -VOID -NvmExpressMakeAddressRangePrivate( - IN NVME_HOST_VISIBILITY_CONTEXT *HostVisibilityContext, - IN OUT VOID *AddressRange - ); \ No newline at end of file diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressDiskInfo.c b/MsvmPkg/NvmExpressDxe/NvmExpressDiskInfo.c deleted file mode 100644 index 9a5ca67300..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressDiskInfo.c +++ /dev/null @@ -1,153 +0,0 @@ -/** @file - This file is used to implement the EFI_DISK_INFO_PROTOCOL interface.. - - Copyright (c) 2013, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "NvmExpress.h" - -EFI_DISK_INFO_PROTOCOL gNvmExpressDiskInfoProtocolTemplate = { - EFI_DISK_INFO_NVME_INTERFACE_GUID, - NvmExpressDiskInfoInquiry, - NvmExpressDiskInfoIdentify, - NvmExpressDiskInfoSenseData, - NvmExpressDiskInfoWhichIde -}; - -/** - Initialize the installation of DiskInfo protocol. - - This function prepares for the installation of DiskInfo protocol on the child handle. - By default, it installs DiskInfo protocol with NVME interface GUID. - - @param[in] Device The pointer of NVME_DEVICE_PRIVATE_DATA. - -**/ -VOID -InitializeDiskInfo ( - IN NVME_DEVICE_PRIVATE_DATA *Device - ) -{ - CopyMem (&Device->DiskInfo, &gNvmExpressDiskInfoProtocolTemplate, sizeof (EFI_DISK_INFO_PROTOCOL)); -} - -/** - Provides inquiry information for the controller type. - - This function is used to get inquiry data. Data format - of Identify data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[in, out] InquiryData Pointer to a buffer for the inquiry data. - @param[in, out] InquiryDataSize Pointer to the value for the inquiry data size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading InquiryData from device - @retval EFI_BUFFER_TOO_SMALL InquiryDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoInquiry ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *InquiryData, - IN OUT UINT32 *InquiryDataSize - ) -{ - return EFI_NOT_FOUND; -} - -/** - Provides identify information for the controller type. - - This function is used to get identify data. Data format - of Identify data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL - instance. - @param[in, out] IdentifyData Pointer to a buffer for the identify data. - @param[in, out] IdentifyDataSize Pointer to the value for the identify data - size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading IdentifyData from device - @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoIdentify ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *IdentifyData, - IN OUT UINT32 *IdentifyDataSize - ) -{ - EFI_STATUS Status; - NVME_DEVICE_PRIVATE_DATA *Device; - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_DISK_INFO (This); - - Status = EFI_BUFFER_TOO_SMALL; - if (*IdentifyDataSize >= sizeof (Device->NamespaceData)) { - Status = EFI_SUCCESS; - CopyMem (IdentifyData, &Device->NamespaceData, sizeof (Device->NamespaceData)); - } - - *IdentifyDataSize = sizeof (Device->NamespaceData); - return Status; -} - -/** - Provides sense data information for the controller type. - - This function is used to get sense data. - Data format of Sense data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[in, out] SenseData Pointer to the SenseData. - @param[in, out] SenseDataSize Size of SenseData in bytes. - @param[out] SenseDataNumber Pointer to the value for the sense data size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class. - @retval EFI_DEVICE_ERROR Error reading SenseData from device. - @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoSenseData ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *SenseData, - IN OUT UINT32 *SenseDataSize, - OUT UINT8 *SenseDataNumber - ) -{ - return EFI_NOT_FOUND; -} - -/** - This function is used to get controller information. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[out] IdeChannel Pointer to the Ide Channel number. Primary or secondary. - @param[out] IdeDevice Pointer to the Ide Device number. Master or slave. - - @retval EFI_SUCCESS IdeChannel and IdeDevice are valid. - @retval EFI_UNSUPPORTED This is not an IDE device. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoWhichIde ( - IN EFI_DISK_INFO_PROTOCOL *This, - OUT UINT32 *IdeChannel, - OUT UINT32 *IdeDevice - ) -{ - return EFI_UNSUPPORTED; -} diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressDiskInfo.h b/MsvmPkg/NvmExpressDxe/NvmExpressDiskInfo.h deleted file mode 100644 index 22135ca262..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressDiskInfo.h +++ /dev/null @@ -1,121 +0,0 @@ -/** @file - Header file for EFI_DISK_INFO_PROTOCOL interface. - -Copyright (c) 2013, Intel Corporation. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _NVME_DISKINFO_H_ -#define _NVME_DISKINFO_H_ - -/** - Initialize the installation of DiskInfo protocol. - - This function prepares for the installation of DiskInfo protocol on the child handle. - By default, it installs DiskInfo protocol with NVME interface GUID. - - @param[in] Device The pointer of NVME_DEVICE_PRIVATE_DATA. - -**/ -VOID -InitializeDiskInfo ( - IN NVME_DEVICE_PRIVATE_DATA *Device - ); - -/** - Provides inquiry information for the controller type. - - This function is used to get inquiry data. Data format - of Identify data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[in, out] InquiryData Pointer to a buffer for the inquiry data. - @param[in, out] InquiryDataSize Pointer to the value for the inquiry data size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading InquiryData from device - @retval EFI_BUFFER_TOO_SMALL InquiryDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoInquiry ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *InquiryData, - IN OUT UINT32 *InquiryDataSize - ); - -/** - Provides identify information for the controller type. - - This function is used to get identify data. Data format - of Identify data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL - instance. - @param[in, out] IdentifyData Pointer to a buffer for the identify data. - @param[in, out] IdentifyDataSize Pointer to the value for the identify data - size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading IdentifyData from device - @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoIdentify ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *IdentifyData, - IN OUT UINT32 *IdentifyDataSize - ); - -/** - Provides sense data information for the controller type. - - This function is used to get sense data. - Data format of Sense data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[in, out] SenseData Pointer to the SenseData. - @param[in, out] SenseDataSize Size of SenseData in bytes. - @param[out] SenseDataNumber Pointer to the value for the sense data size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class. - @retval EFI_DEVICE_ERROR Error reading SenseData from device. - @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoSenseData ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *SenseData, - IN OUT UINT32 *SenseDataSize, - OUT UINT8 *SenseDataNumber - ); - -/** - This function is used to get controller information. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[out] IdeChannel Pointer to the Ide Channel number. Primary or secondary. - @param[out] IdeDevice Pointer to the Ide Device number. Master or slave. - - @retval EFI_SUCCESS IdeChannel and IdeDevice are valid. - @retval EFI_UNSUPPORTED This is not an IDE device. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoWhichIde ( - IN EFI_DISK_INFO_PROTOCOL *This, - OUT UINT32 *IdeChannel, - OUT UINT32 *IdeDevice - ); - -#endif diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressDxe.inf b/MsvmPkg/NvmExpressDxe/NvmExpressDxe.inf deleted file mode 100644 index 3e99b735c1..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressDxe.inf +++ /dev/null @@ -1,101 +0,0 @@ -## @file -# NVM Express Host Controller Module. -# -# NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows -# NVM Express specification. -# -# Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
-# Copyright (c) Microsoft Corporation.
-# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -#Override : 00000002 | MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf | bc15ab4a6687a3445fd2152860f80fe7 | 2026-04-28T00-00-00 | 3d43ac3575cdd6ffa7ac36c7ff50d190c8a58097 - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = NvmExpressDxe - MODULE_UNI_FILE = NvmExpressDxe.uni - FILE_GUID = 5BE3BDF4-53CF-46a3-A6A9-73C34A6E5EE3 - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = NvmExpressDriverEntry - UNLOAD_IMAGE = NvmExpressUnload - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 EBC -# -# DRIVER_BINDING = gNvmExpressDriverBinding -# COMPONENT_NAME = gNvmExpressComponentName -# COMPONENT_NAME2 = gNvmExpressComponentName2 - -[Sources] - NvmExpressBlockIo.c - NvmExpressBlockIo.h - ComponentName.c - NvmExpress.c - NvmExpress.h - NvmExpressBounce.c ## MS_HYP_CHANGE - NvmExpressDiskInfo.c - NvmExpressDiskInfo.h - NvmExpressHci.c - NvmExpressHci.h - NvmExpressPassthru.c - NvmExpressMediaSanitize.c - NvmExpressMediaSanitize.h - -[Guids] - gNVMeEnableStartEventGroupGuid - gNVMeEnableCompleteEventGroupGuid - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - MsvmPkg/MsvmPkg.dec ## MS_HYP_CHANGE - -[LibraryClasses] - BaseMemoryLib - BaseLib - DebugLib - DevicePathLib - IsolationLib ## MS_HYP_CHANGE - MemoryAllocationLib - UefiDriverEntryPoint - UefiBootServicesTableLib - UefiLib - PrintLib - ReportStatusCodeLib - -[Protocols] - gEfiPciIoProtocolGuid ## TO_START - ## BY_START - ## TO_START - gEfiDevicePathProtocolGuid - gEfiNvmExpressPassThruProtocolGuid ## BY_START - gEfiBlockIoProtocolGuid ## BY_START - gEfiBlockIo2ProtocolGuid ## BY_START - gEfiDiskInfoProtocolGuid ## BY_START - gEfiStorageSecurityCommandProtocolGuid ## BY_START - gEfiDriverSupportedEfiVersionProtocolGuid ## PRODUCES - gMediaSanitizeProtocolGuid ## PRODUCES - gEfiResetNotificationProtocolGuid ## CONSUMES - gEfiHvIvmProtocolGuid ## CONSUMES ## MS_HYP_CHANGE - -[Pcd] - ## MU_CHANGE [BEGIN] - Support alternative hardware queue sizes in NVME driver - gEfiMdeModulePkgTokenSpaceGuid.PcdSupportAlternativeQueueSize ## CONSUMES - ## MU_CHANGE [END] - Support alternative hardware queue sizes in NVME driver - ## MU_CHANGE [BEGIN] - NVMe namespace filtering - gEfiMdeModulePkgTokenSpaceGuid.PcdNvmeNamespaceFilterId ## CONSUMES - ## MU_CHANGE [END] - NVMe namespace filtering - gMsvmPkgTokenSpaceGuid.PcdIsolationSharedGpaBoundary ## MS_HYP_CHANGE - gMsvmPkgTokenSpaceGuid.PcdIsolationSharedGpaCanonicalizationBitmask ## MS_HYP_CHANGE - -# [Event] -# EVENT_TYPE_RELATIVE_TIMER ## SOMETIMES_CONSUMES -# - -[UserExtensions.TianoCore."ExtraFiles"] - NvmExpressDxeExtra.uni diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressDxe.uni b/MsvmPkg/NvmExpressDxe/NvmExpressDxe.uni deleted file mode 100644 index 829be6bbe7..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressDxe.uni +++ /dev/null @@ -1,17 +0,0 @@ -// /** @file -// NVM Express Host Controller Module. -// -// NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows -// NVM Express specification. -// -// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
-// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "NVM Express Host Controller Module" - -#string STR_MODULE_DESCRIPTION #language en-US "NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows NVM Express specification." - diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressDxeExtra.uni b/MsvmPkg/NvmExpressDxe/NvmExpressDxeExtra.uni deleted file mode 100644 index c74e13d871..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressDxeExtra.uni +++ /dev/null @@ -1,14 +0,0 @@ -// /** @file -// NvmExpressDxe Localized Strings and Content -// -// Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.
-// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"NVM Express DXE Driver" - - diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressHci.c b/MsvmPkg/NvmExpressDxe/NvmExpressHci.c deleted file mode 100644 index 91b4d20cde..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressHci.c +++ /dev/null @@ -1,1815 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "NvmExpress.h" -#include - -#define NVME_SHUTDOWN_PROCESS_TIMEOUT 45 - -// -// The number of NVME controllers managed by this driver, used by -// NvmeRegisterShutdownNotification() and NvmeUnregisterShutdownNotification(). -// -UINTN mNvmeControllerNumber = 0; - -/** - Read Nvm Express controller capability register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Cap The buffer used to store capability register content. - - @return EFI_SUCCESS Successfully read the controller capability register content. - @return EFI_DEVICE_ERROR Fail to read the controller capability register. - -**/ -EFI_STATUS -ReadNvmeControllerCapabilities ( - // MU_CHANGE [BEGIN] - Correct Cap parameter modifier - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - OUT NVME_CAP *Cap - // MU_CHANGE [END] - Correct Cap parameter modifier - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT64 Data; - - PciIo = Private->PciIo; - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CAP_OFFSET, - 2, - &Data - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - WriteUnaligned64 ((UINT64 *)Cap, Data); - return EFI_SUCCESS; -} - -/** - Read Nvm Express controller configuration register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Cc The buffer used to store configuration register content. - - @return EFI_SUCCESS Successfully read the controller configuration register content. - @return EFI_DEVICE_ERROR Fail to read the controller configuration register. - -**/ -EFI_STATUS -ReadNvmeControllerConfiguration ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_CC *Cc - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 Data; - - PciIo = Private->PciIo; - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CC_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - WriteUnaligned32 ((UINT32 *)Cc, Data); - return EFI_SUCCESS; -} - -/** - Write Nvm Express controller configuration register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Cc The buffer used to store the content to be written into configuration register. - - @return EFI_SUCCESS Successfully write data into the controller configuration register. - @return EFI_DEVICE_ERROR Fail to write data into the controller configuration register. - -**/ -EFI_STATUS -WriteNvmeControllerConfiguration ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_CC *Cc - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 Data; - - PciIo = Private->PciIo; - Data = ReadUnaligned32 ((UINT32 *)Cc); - Status = PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CC_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG ((DEBUG_INFO, "Cc.En: %d\n", Cc->En)); - DEBUG ((DEBUG_INFO, "Cc.Css: %d\n", Cc->Css)); - DEBUG ((DEBUG_INFO, "Cc.Mps: %d\n", Cc->Mps)); - DEBUG ((DEBUG_INFO, "Cc.Ams: %d\n", Cc->Ams)); - DEBUG ((DEBUG_INFO, "Cc.Shn: %d\n", Cc->Shn)); - DEBUG ((DEBUG_INFO, "Cc.Iosqes: %d\n", Cc->Iosqes)); - DEBUG ((DEBUG_INFO, "Cc.Iocqes: %d\n", Cc->Iocqes)); - - return EFI_SUCCESS; -} - -/** - Read Nvm Express controller status register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Csts The buffer used to store status register content. - - @return EFI_SUCCESS Successfully read the controller status register content. - @return EFI_DEVICE_ERROR Fail to read the controller status register. - -**/ -EFI_STATUS -ReadNvmeControllerStatus ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_CSTS *Csts - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 Data; - - PciIo = Private->PciIo; - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CSTS_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - WriteUnaligned32 ((UINT32 *)Csts, Data); - return EFI_SUCCESS; -} - -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - -/** - Read Nvm Express admin queue attributes register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Aqa The buffer used to store the content to be read from admin queue attributes register. - - @return EFI_SUCCESS Successfully read data from the admin queue attributes register. - @return EFI_DEVICE_ERROR Fail to read data from the admin queue attributes register. - -**/ -EFI_STATUS -ReadNvmeAdminQueueAttributes ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - OUT NVME_AQA *Aqa - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 Data; - - PciIo = Private->PciIo; - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_AQA_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - WriteUnaligned32 ((UINT32 *)Aqa, Data); - - DEBUG ((DEBUG_INFO, "%a: Admin Submission Queue Size (Number of Entries): %d\n", __func__, Aqa->Asqs)); - DEBUG ((DEBUG_INFO, "%a: Admin Completion Queue Size (Number of Entries): %d\n", __func__, Aqa->Acqs)); - - return EFI_SUCCESS; -} - -// MU_CHANGE [END] - Allocate IO Queue Buffer - -/** - Write Nvm Express admin queue attributes register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Aqa The buffer used to store the content to be written into admin queue attributes register. - - @return EFI_SUCCESS Successfully write data into the admin queue attributes register. - @return EFI_DEVICE_ERROR Fail to write data into the admin queue attributes register. - -**/ -EFI_STATUS -WriteNvmeAdminQueueAttributes ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_AQA *Aqa - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 Data; - - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - // - // Save Aqa to Private data for later use. - // - Private->SqData[0].NumberOfEntries = Aqa->Asqs; - Private->CqData[0].NumberOfEntries = Aqa->Acqs; - // MU_CHANGE [END] - Allocate IO Queue Buffer - - PciIo = Private->PciIo; - Data = ReadUnaligned32 ((UINT32 *)Aqa); - Status = PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_AQA_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG ((DEBUG_INFO, "Aqa.Asqs: %d\n", Aqa->Asqs)); - DEBUG ((DEBUG_INFO, "Aqa.Acqs: %d\n", Aqa->Acqs)); - - return EFI_SUCCESS; -} - -/** - Write Nvm Express admin submission queue base address register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Asq The buffer used to store the content to be written into admin submission queue base address register. - - @return EFI_SUCCESS Successfully write data into the admin submission queue base address register. - @return EFI_DEVICE_ERROR Fail to write data into the admin submission queue base address register. - -**/ -EFI_STATUS -WriteNvmeAdminSubmissionQueueBaseAddress ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_ASQ *Asq - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT64 Data; - - PciIo = Private->PciIo; - Data = ReadUnaligned64 ((UINT64 *)Asq); - - Status = PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_ASQ_OFFSET, - 2, - &Data - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG ((DEBUG_INFO, "Asq: %lx\n", *Asq)); - - return EFI_SUCCESS; -} - -/** - Write Nvm Express admin completion queue base address register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Acq The buffer used to store the content to be written into admin completion queue base address register. - - @return EFI_SUCCESS Successfully write data into the admin completion queue base address register. - @return EFI_DEVICE_ERROR Fail to write data into the admin completion queue base address register. - -**/ -EFI_STATUS -WriteNvmeAdminCompletionQueueBaseAddress ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_ACQ *Acq - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT64 Data; - - PciIo = Private->PciIo; - Data = ReadUnaligned64 ((UINT64 *)Acq); - - Status = PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_ACQ_OFFSET, - 2, - &Data - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG ((DEBUG_INFO, "Acq: %lxh\n", *Acq)); - - return EFI_SUCCESS; -} - -/** - Disable the Nvm Express controller. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @return EFI_SUCCESS Successfully disable the controller. - @return EFI_DEVICE_ERROR Fail to disable the controller. - -**/ -EFI_STATUS -NvmeDisableController ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - NVME_CC Cc; - NVME_CSTS Csts; - EFI_STATUS Status; - UINT32 Index; - UINT8 Timeout; - - // - // Read Controller Configuration Register. - // - Status = ReadNvmeControllerConfiguration (Private, &Cc); - if (EFI_ERROR (Status)) { - return Status; - } - - Cc.En = 0; - - // - // Disable the controller. - // - Status = WriteNvmeControllerConfiguration (Private, &Cc); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Cap.To specifies max delay time in 500ms increments for Csts.Rdy to transition from 1 to 0 after - // Cc.Enable transition from 1 to 0. Loop produces a 1 millisecond delay per itteration, up to 500 * Cap.To. - // - if (Private->Cap.To == 0) { - Timeout = 1; - } else { - Timeout = Private->Cap.To; - } - - for (Index = (Timeout * 500); Index != 0; --Index) { - gBS->Stall (1000); - - // - // Check if the controller is initialized - // - Status = ReadNvmeControllerStatus (Private, &Csts); - - if (EFI_ERROR (Status)) { - return Status; - } - - if (Csts.Rdy == 0) { - break; - } - } - - if (Index == 0) { - Status = EFI_DEVICE_ERROR; - REPORT_STATUS_CODE ( - (EFI_ERROR_CODE | EFI_ERROR_MAJOR), - (EFI_IO_BUS_SCSI | EFI_IOB_EC_INTERFACE_ERROR) - ); - } - - DEBUG ((DEBUG_INFO, "NVMe controller is disabled with status [%r].\n", Status)); - return Status; -} - -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - -/** - Enable the Nvm Express controller. Allocate and write the Controller Configuration data. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param IoSqEs The I/O Submission Queue Entry Size. - @param IoCqEs The I/O Completion Queue Entry Size. - - @return EFI_SUCCESS Successfully enable the controller. - @return EFI_DEVICE_ERROR Fail to enable the controller. - @return EFI_TIMEOUT Fail to enable the controller in given time slot. - -**/ -EFI_STATUS -NvmeEnableController ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT8 IoSqEs, - IN UINT8 IoCqEs - ) -{ - // MU_CHANGE [END] - Allocate IO Queue Buffer - NVME_CC Cc; - NVME_CSTS Csts; - EFI_STATUS Status; - UINT32 Index; - UINT8 Timeout; - - EfiEventGroupSignal (&gNVMeEnableStartEventGroupGuid); - - // - // Enable the controller. - // CC.AMS, CC.MPS and CC.CSS are all set to 0. - // - ZeroMem (&Cc, sizeof (NVME_CC)); - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - Cc.En = 1; - Cc.Iosqes = IoSqEs; - Cc.Iocqes = IoCqEs; - // MU_CHANGE [END] - Allocate IO Queue Buffer - - Status = WriteNvmeControllerConfiguration (Private, &Cc); - if (EFI_ERROR (Status)) { - goto Cleanup; - } - - // - // Cap.To specifies max delay time in 500ms increments for Csts.Rdy to set after - // Cc.Enable. Loop produces a 1 millisecond delay per itteration, up to 500 * Cap.To. - // - if (Private->Cap.To == 0) { - Timeout = 1; - } else { - Timeout = Private->Cap.To; - } - - for (Index = (Timeout * 500); Index != 0; --Index) { - gBS->Stall (1000); - - // - // Check if the controller is initialized - // - Status = ReadNvmeControllerStatus (Private, &Csts); - - if (EFI_ERROR (Status)) { - goto Cleanup; - } - - if (Csts.Rdy) { - break; - } - } - - if (Index == 0) { - Status = EFI_TIMEOUT; - REPORT_STATUS_CODE ( - (EFI_ERROR_CODE | EFI_ERROR_MAJOR), - (EFI_IO_BUS_SCSI | EFI_IOB_EC_INTERFACE_ERROR) - ); - } - - DEBUG ((DEBUG_INFO, "NVMe controller is enabled with status [%r].\n", Status)); - -Cleanup: - EfiEventGroupSignal (&gNVMeEnableCompleteEventGroupGuid); - return Status; -} - -/** - Get identify controller data. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Buffer The buffer used to store the identify controller data. - - @return EFI_SUCCESS Successfully get the identify controller data. - @return EFI_DEVICE_ERROR Fail to get the identify controller data. - -**/ -EFI_STATUS -NvmeIdentifyController ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN VOID *Buffer - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - - Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD; - // - // According to Nvm Express 1.1 spec Figure 38, When not used, the field shall be cleared to 0h. - // For the Identify command, the Namespace Identifier is only used for the Namespace data structure. - // - Command.Nsid = 0; - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - CommandPacket.TransferBuffer = Buffer; - CommandPacket.TransferLength = sizeof (NVME_ADMIN_CONTROLLER_DATA); - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - // - // Set bit 0 (Cns bit) to 1 to identify a controller - // - Command.Cdw10 = 1; - Command.Flags = CDW10_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - NVME_CONTROLLER_ID, - &CommandPacket, - NULL - ); - - return Status; -} - -/** - Get specified identify namespace data. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param NamespaceId The specified namespace identifier. - @param Buffer The buffer used to store the identify namespace data. - - @return EFI_SUCCESS Successfully get the identify namespace data. - @return EFI_DEVICE_ERROR Fail to get the identify namespace data. - -**/ -EFI_STATUS -NvmeIdentifyNamespace ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT32 NamespaceId, - IN VOID *Buffer - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD; - Command.Nsid = NamespaceId; - CommandPacket.TransferBuffer = Buffer; - CommandPacket.TransferLength = sizeof (NVME_ADMIN_NAMESPACE_DATA); - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - // - // Set bit 0 (Cns bit) to 1 to identify a namespace - // - CommandPacket.NvmeCmd->Cdw10 = 0; - CommandPacket.NvmeCmd->Flags = CDW10_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - NamespaceId, - &CommandPacket, - NULL - ); - - return Status; -} - -// MU_CHANGE [BEGIN] - Request Number of Queues from Controller - -/** - Send the Set Features Command to the controller for the number of queues requested. - Note that the number of queues allocated may be different from the number of queues requested. - The number of data queue pairs allocated is returned and stored in the controller private data structure - using the NumberOfIoQueuePairs field. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Ndqpr The number of data queue pairs requested. - - @return EFI_SUCCESS Successfully set the number of queues. - @return EFI_DEVICE_ERROR Fail to set the number of queues. - -**/ -EFI_STATUS -NvmeSetFeaturesNumberOfQueues ( - IN OUT NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT16 Ndqpr - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - NVME_ADMIN_SET_FEATURES_CDW10 SetFeatures; - NVME_ADMIN_SET_FEATURES_NUM_QUEUES NumberOfQueuesRequested; - NVME_ADMIN_SET_FEATURES_NUM_QUEUES NumberOfQueuesAllocated; - - Status = EFI_SUCCESS; - - if (Ndqpr == 0) { - DEBUG ((DEBUG_ERROR, "Number of Data Queue Pairs Requested cannot be 0\n")); - return EFI_INVALID_PARAMETER; - } - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - ZeroMem (&SetFeatures, sizeof (NVME_ADMIN_SET_FEATURES)); - ZeroMem (&NumberOfQueuesRequested, sizeof (NVME_ADMIN_SET_FEATURES_NUM_QUEUES)); - ZeroMem (&NumberOfQueuesAllocated, sizeof (NVME_ADMIN_SET_FEATURES_NUM_QUEUES)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - Command.Nsid = 0; // NSID must be set to 0h or FFFFFFFFh for an admin command - Command.Cdw0.Opcode = NVME_ADMIN_SET_FEATURES_CMD; - - // Populate the Set Features Cdw10 and Cdw11 according to Nvm Express 1.3d Spec - // Note we subtract 1 from the requested number of queues to get the 0-based value - SetFeatures.Bits.Fid = NVME_FEATURE_NUMBER_OF_QUEUES; - NumberOfQueuesRequested.Bits.Ncq = Ndqpr - 1; - NumberOfQueuesRequested.Bits.Nsq = Ndqpr - 1; - CommandPacket.NvmeCmd->Cdw10 = SetFeatures.Uint32; - CommandPacket.NvmeCmd->Cdw11 = NumberOfQueuesRequested.Uint32; - - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID; - - DEBUG ((DEBUG_INFO, "Number of Data Queue Pairs Requested: %d\n", Ndqpr)); - - // Send the Set Features Command for Number of Queues - Status = Private->Passthru.PassThru ( - &Private->Passthru, - 0, - &CommandPacket, - NULL - ); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Set Features Command for Number of Queues failed with Status %r\n", Status)); - return Status; - } - - // - // Save the number of queues allocated, adding 1 to account for it being a 0-based value. - // E.g. if 1 pair of data queues is allocated Nsq=0, Ncq=0, then NumberOfIoQueuePairs=1. - // These numbers do not include the admin queues. - // - NumberOfQueuesAllocated.Uint32 = CommandPacket.NvmeCompletion->DW0; - DEBUG ((DEBUG_INFO, "Number of Data Queue Pairs Allocated By Controller: %d, \n", (NumberOfQueuesAllocated.Bits.Nsq + 1))); - if ((NumberOfQueuesAllocated.Bits.Nsq + 1) > Ndqpr) { - // This driver at maximum supports 2 pairs of data queues. So we will take the minimum of the requested and allocated values. - Private->NumberOfIoQueuePairs = Ndqpr; - } else { - Private->NumberOfIoQueuePairs = NumberOfQueuesAllocated.Bits.Nsq + 1; - } - - DEBUG ((DEBUG_INFO, "Number of Data Queue Pairs Supported By Driver: %d, \n", Private->NumberOfIoQueuePairs)); - return Status; -} - -// MU_CHANGE [END] - Request Number of Queues from Controller - -/** - Create io completion queue(s). - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @return EFI_SUCCESS Successfully create io completion queue. - @return EFI_DEVICE_ERROR Fail to create io completion queue. - -**/ -EFI_STATUS -NvmeCreateIoCompletionQueue ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - NVME_ADMIN_CRIOCQ CrIoCq; - UINT32 Index; - UINT16 QueueSize; - - Status = EFI_SUCCESS; - Private->CreateIoQueue = TRUE; - - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - // Start from Index 1 because Index 0 is reserved for admin queue - for (Index = 1; Index <= Private->NumberOfIoQueuePairs; Index++) { - // MU_CHANGE [END] - Request Number of Queues from Controller - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - ZeroMem (&CrIoCq, sizeof (NVME_ADMIN_CRIOCQ)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - Command.Cdw0.Opcode = NVME_ADMIN_CRIOCQ_CMD; - CommandPacket.TransferBuffer = Private->CqBufferPciAddr[Index]; - CommandPacket.TransferLength = EFI_PAGE_SIZE; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - - // MU_CHANGE [BEGIN] - Use the Mqes value from the Cap register - // MU_CHANGE [BEGIN] - Support alternative hardware queue sizes in NVME driver - if (PcdGetBool (PcdSupportAlternativeQueueSize)) { - QueueSize = MIN (NVME_ALTERNATIVE_MAX_QUEUE_SIZE, Private->Cap.Mqes); - } else if (Index == 1) { - // MU_CHANGE [END] - Support alternative hardware queue sizes in NVME driver - QueueSize = MIN (NVME_CCQ_SIZE, Private->Cap.Mqes); - } else { - QueueSize = MIN (NVME_ASYNC_CCQ_SIZE, Private->Cap.Mqes); - } - - // MU_CHANGE [END] - Use the Mqes value from the Cap register - - CrIoCq.Qid = Index; - CrIoCq.Qsize = QueueSize; - CrIoCq.Pc = 1; - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof (NVME_ADMIN_CRIOCQ)); - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - 0, - &CommandPacket, - NULL - ); - if (EFI_ERROR (Status)) { - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - DEBUG ((DEBUG_ERROR, "%a: Create Completion Queue Command %d failed with Status %r\n", __func__, Index, Status)); - // MU_CHANGE [END] - Request Number of Queues from Controller - break; - } - } - - Private->CreateIoQueue = FALSE; - - return Status; -} - -/** - Create io submission queue. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @return EFI_SUCCESS Successfully create io submission queue. - @return EFI_DEVICE_ERROR Fail to create io submission queue. - -**/ -EFI_STATUS -NvmeCreateIoSubmissionQueue ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - NVME_ADMIN_CRIOSQ CrIoSq; - UINT32 Index; - UINT16 QueueSize; - - Status = EFI_SUCCESS; - Private->CreateIoQueue = TRUE; - - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - // Start from Index 1 because Index 0 is reserved for admin queue - for (Index = 1; Index <= Private->NumberOfIoQueuePairs; Index++) { - // MU_CHANGE [END] - Request Number of Queues from Controller - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - ZeroMem (&CrIoSq, sizeof (NVME_ADMIN_CRIOSQ)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - Command.Cdw0.Opcode = NVME_ADMIN_CRIOSQ_CMD; - CommandPacket.TransferBuffer = Private->SqBufferPciAddr[Index]; - CommandPacket.TransferLength = EFI_PAGE_SIZE; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - - // MU_CHANGE [BEGIN] - Use the Mqes value from the Cap register - // MU_CHANGE [BEGIN] - Support alternative hardware queue sizes in NVME driver - if (PcdGetBool (PcdSupportAlternativeQueueSize)) { - QueueSize = MIN (NVME_ALTERNATIVE_MAX_QUEUE_SIZE, Private->Cap.Mqes); - } else if (Index == 1) { - // MU_CHANGE [END] - Support alternative hardware queue sizes in NVME driver - QueueSize = MIN (NVME_CSQ_SIZE, Private->Cap.Mqes); - } else { - QueueSize = MIN (NVME_ASYNC_CSQ_SIZE, Private->Cap.Mqes); - } - - // MU_CHANGE [END] - Use the Mqes value from the Cap register - - CrIoSq.Qid = Index; - CrIoSq.Qsize = QueueSize; - CrIoSq.Pc = 1; - CrIoSq.Cqid = Index; - CrIoSq.Qprio = 0; - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoSq, sizeof (NVME_ADMIN_CRIOSQ)); - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - 0, - &CommandPacket, - NULL - ); - if (EFI_ERROR (Status)) { - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - DEBUG ((DEBUG_ERROR, "%a: Create Submission Queue Command %d failed with Status %r\n", __func__, Index, Status)); - // MU_CHANGE [END] - Request Number of Queues from Controller - break; - } - } - - Private->CreateIoQueue = FALSE; - - return Status; -} - -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - -/** - Initialize the Nvm Express controller Data (IO) Queues - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS The NVM Express Controller IO Queues are initialized successfully. - @retval Others A device error occurred while initializing the IO Queues. - -**/ -EFI_STATUS -NvmeControllerInitIoQueues ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - UINTN SqPageCount; - UINTN IoQueuePairPageCount; - UINT32 Index; - EFI_STATUS Status; - - // Offset completion queue with submission queue size - SqPageCount = NVME_SQ_SIZE_IN_PAGES (Private, 1); - - // Calculate the number of pages required for the data queues - IoQueuePairPageCount = SqPageCount + NVME_CQ_SIZE_IN_PAGES (Private, 1); - - // - // Address of Data I/O submission & completion queue(s). - // We are using the same table of buffer pointers that the admin queues are in, so we start the table from Index + 1, but we have a separate - // buffer so we start at the beginning of that buffer. - // - ZeroMem (Private->IoQueueBuffer, EFI_PAGES_TO_SIZE (IoQueuePairPageCount) * Private->NumberOfIoQueuePairs); - for (Index = 0; Index < Private->NumberOfIoQueuePairs; Index++) { - Private->SqBuffer[Index + 1] = (NVME_SQ *)(UINTN)(Private->IoQueueBuffer + EFI_PAGES_TO_SIZE (Index * IoQueuePairPageCount)); - Private->SqBufferPciAddr[Index + 1] = (NVME_SQ *)(UINTN)(Private->IoQueueBufferPciAddr + EFI_PAGES_TO_SIZE (Index * IoQueuePairPageCount)); - Private->CqBuffer[Index + 1] = (NVME_CQ *)(UINTN)(Private->IoQueueBuffer + EFI_PAGES_TO_SIZE (Index * IoQueuePairPageCount + SqPageCount)); - Private->CqBufferPciAddr[Index + 1] = (NVME_CQ *)(UINTN)(Private->IoQueueBufferPciAddr + EFI_PAGES_TO_SIZE (Index * IoQueuePairPageCount + SqPageCount)); - - DEBUG ((DEBUG_INFO, "Data IO Submission Queue (SqBuffer[%d]) = [%016X]\n", Index + 1, Private->SqBuffer[Index + 1])); - DEBUG ((DEBUG_INFO, "Data IO Completion Queue (CqBuffer[%d]) = [%016X]\n", Index + 1, Private->CqBuffer[Index + 1])); - } - - // - // Create I/O completion queue(s). - // - Status = NvmeCreateIoCompletionQueue (Private); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Create I/O Submission queue(s). - // - Status = NvmeCreateIoSubmissionQueue (Private); - - return Status; -} - -// MU_CHANGE [END] - Allocate IO Queue Buffer - -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - -/** - Initialize the Nvm Express controller Admin Queues - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS The NVM Express Controller is initialized successfully. - @retval Others A device error occurred while initializing the controller. - -**/ -EFI_STATUS -NvmeControllerInitAdminQueues ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - NVME_ASQ Asq; - NVME_ACQ Acq; - UINTN AsqPageCount; - UINTN AsqSize; - UINTN AdminQueuePairPageCount; - EFI_STATUS Status; - - // Offset completion queue with submission queue size - AsqPageCount = NVME_SQ_SIZE_IN_PAGES (Private, 0); - AsqSize = EFI_PAGES_TO_SIZE (AsqPageCount); - - // - // Address of admin submission queue. - // - // MU_CHANGE - Remove Page Mask - Asq = (UINT64)(UINTN)(Private->BufferPciAddr); - - // - // Address of admin completion queue. - // - // MU_CHANGE - Remove Page Mask - Acq = (UINT64)(UINTN)(Private->BufferPciAddr + AsqSize); - - // Calculate the number of pages required for the admin queues - AdminQueuePairPageCount = AsqPageCount + NVME_CQ_SIZE_IN_PAGES (Private, 0); - - // - // Address of Admin I/O submission & completion queues. - // - ZeroMem (Private->Buffer, EFI_PAGES_TO_SIZE (AdminQueuePairPageCount)); - Private->SqBuffer[0] = (NVME_SQ *)(UINTN)(Private->Buffer); - Private->SqBufferPciAddr[0] = (NVME_SQ *)(UINTN)(Private->BufferPciAddr); - Private->CqBuffer[0] = (NVME_CQ *)(UINTN)(Private->Buffer + AsqSize); - Private->CqBufferPciAddr[0] = (NVME_CQ *)(UINTN)(Private->BufferPciAddr + AsqSize); - - DEBUG ((DEBUG_INFO, "Private->Buffer = [%016X]\n", (UINT64)(UINTN)Private->Buffer)); - DEBUG ((DEBUG_INFO, "Admin Submission Queue size (Number of Entries) = [%08X]\n", Private->SqData[0].NumberOfEntries)); - DEBUG ((DEBUG_INFO, "Admin Completion Queue size (Number of Entries) = [%08X]\n", Private->CqData[0].NumberOfEntries)); - DEBUG ((DEBUG_INFO, "Admin Submission Queue (SqBuffer[0]) = [%016X]\n", Private->SqBuffer[0])); - DEBUG ((DEBUG_INFO, "Admin Completion Queue (CqBuffer[0]) = [%016X]\n", Private->CqBuffer[0])); - - // - // Program admin submission queue address. - // - Status = WriteNvmeAdminSubmissionQueueBaseAddress (Private, &Asq); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Program admin completion queue address. - // - Status = WriteNvmeAdminCompletionQueueBaseAddress (Private, &Acq); - - return Status; -} - -// MU_CHANGE [END] - Allocate IO Queue Buffer - -/** - Initialize the Nvm Express controller. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS The NVM Express Controller is initialized successfully. - @retval Others A device error occurred while initializing the controller. - -**/ -EFI_STATUS -NvmeControllerInit ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 Supports; - UINT16 VidDid[2]; // MU_CHANGE - Improve NVMe controller init robustness - // NVME_ASQ Asq; - // NVME_ACQ Acq; - UINT8 Sn[21]; - UINT8 Mn[41]; - UINTN Bytes; - UINT32 Index; - EFI_PHYSICAL_ADDRESS MappedAddr; - NVME_AQA Aqa; - UINTN AdminQueuePairPageCount; - UINTN IoQueuePairPageCount; - - // MU_CHANGE [END] - Allocate IO Queue Buffer - - // MU_CHANGE [BEGIN] - Improve NVMe controller init robustness - PciIo = Private->PciIo; - - // - // Verify the controller is still accessible - // - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - PCI_VENDOR_ID_OFFSET, - ARRAY_SIZE (VidDid), - VidDid - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return EFI_DEVICE_ERROR; - } - - if ((VidDid[0] == NVME_INVALID_VID_DID) || (VidDid[1] == NVME_INVALID_VID_DID)) { - return EFI_DEVICE_ERROR; - } - - // MU_CHANGE [END] - Improve NVMe controller init robustness - - // - // Enable this controller. - // - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - - if (!EFI_ERROR (Status)) { - Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - } - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "NvmeControllerInit: failed to enable controller\n")); - return Status; - } - - // - // Read the Controller Capabilities register and verify that the NVM command set is supported - // - Status = ReadNvmeControllerCapabilities (Private, &Private->Cap); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((Private->Cap.Css & BIT0) == 0) { - DEBUG ((DEBUG_INFO, "NvmeControllerInit: the controller doesn't support NVMe command set\n")); - return EFI_UNSUPPORTED; - } - - // - // Currently the driver only supports 4k page size. - // - // MU_CHANGE [BEGIN] - Improve NVMe controller init robustness - - // Currently, this means Cap.Mpsmin must be zero for an EFI_PAGE_SHIFT size of 12. - // ASSERT ((Private->Cap.Mpsmin + 12) <= EFI_PAGE_SHIFT); - if ((Private->Cap.Mpsmin + 12) > EFI_PAGE_SHIFT) { - DEBUG ((DEBUG_ERROR, "NvmeControllerInit: Mpsmin is larger than expected (0x%02x).\n", Private->Cap.Mpsmin)); - return EFI_DEVICE_ERROR; - } - - // MU_CHANGE [END] - Improve NVMe controller init robustness - - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - - // Private->Cid[0] = 0; - // Private->Cid[1] = 0; - // Private->Cid[2] = 0; - // Private->Pt[0] = 0; - // Private->Pt[1] = 0; - // Private->Pt[2] = 0; - // Private->SqTdbl[0].Sqt = 0; - // Private->SqTdbl[1].Sqt = 0; - // Private->SqTdbl[2].Sqt = 0; - // Private->CqHdbl[0].Cqh = 0; - // Private->CqHdbl[1].Cqh = 0; - // Private->CqHdbl[2].Cqh = 0; - // Private->AsyncSqHead = 0; - - for (Index = 0; Index < NVME_MAX_QUEUES; Index++) { - Private->Cid[Index] = 0; - Private->Pt[Index] = 0; - Private->SqTdbl[Index].Sqt = 0; - Private->CqHdbl[Index].Cqh = 0; - } - - Private->AsyncSqHead = 0; - - // - // set number of entries admin submission & completion queues. - // - // MU_CHANGE [BEGIN] - Support alternative hardware queue sizes in NVME driver - Aqa.Asqs = PcdGetBool (PcdSupportAlternativeQueueSize) ? MIN (NVME_ALTERNATIVE_MAX_QUEUE_SIZE, Private->Cap.Mqes) : MIN (NVME_ASQ_SIZE, Private->Cap.Mqes); - Aqa.Rsvd1 = 0; - Aqa.Acqs = PcdGetBool (PcdSupportAlternativeQueueSize) ? MIN (NVME_ALTERNATIVE_MAX_QUEUE_SIZE, Private->Cap.Mqes) : MIN (NVME_ACQ_SIZE, Private->Cap.Mqes); - Aqa.Rsvd2 = 0; - // MU_CHANGE [END] - Support alternative hardware queue sizes in NVME driver - - // - // Set admin queue entry size to default - // Note we are using the spec-defined minimum SQES and CQES here. - // - Private->SqData[0].EntrySize = NVME_IOSQES_MIN; - Private->SqData[0].NumberOfEntries = Aqa.Asqs; - Private->CqData[0].EntrySize = NVME_IOCQES_MIN; - Private->CqData[0].NumberOfEntries = Aqa.Acqs; - - // Calculate the number of pages required for the admin queues - AdminQueuePairPageCount = NVME_SQ_SIZE_IN_PAGES (Private, 0) + NVME_CQ_SIZE_IN_PAGES (Private, 0); - - // - // Default: - // 6 x 4kB aligned buffers will be carved out of this buffer. - // 1st 4kB boundary is the start of the admin submission queue. - // 2nd 4kB boundary is the start of the admin completion queue. - // 3rd 4kB boundary is the start of I/O submission queue #1. - // 4th 4kB boundary is the start of I/O completion queue #1. - // 5th 4kB boundary is the start of I/O submission queue #2. - // 6th 4kB boundary is the start of I/O completion queue #2. - // - // Allocate 6 pages of memory, then map it for bus master read and write. - // - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - AdminQueuePairPageCount, - (VOID **)&Private->Buffer, - 0 - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // MS_HYP_CHANGE BEGIN - if (IsIsolated()) { - Status = NvmExpressMakeAddressRangeShared(&Private->QueueVisibilityContext, - Private->Buffer, - (UINT32)AdminQueuePairPageCount * EFI_PAGE_SIZE - ); - - if (EFI_ERROR (Status)) { - EFI_STATUS FreeStatus = PciIo->FreeBuffer (PciIo, AdminQueuePairPageCount, Private->Buffer); - - if (EFI_ERROR (FreeStatus)) { - DEBUG ((DEBUG_ERROR, "%a: FreeBuffer Admin Queue Buffer failed %r\n", __func__, FreeStatus)); - ASSERT_EFI_ERROR (FreeStatus); - } - - Private->Buffer = NULL; - return Status; - } - } - // MS_HYP_CHANGE END - - Bytes = EFI_PAGES_TO_SIZE (AdminQueuePairPageCount); - Status = PciIo->Map ( - PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - Private->Buffer, - &Bytes, - &MappedAddr, - &Private->Mapping - ); - if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (AdminQueuePairPageCount))) { - return EFI_DEVICE_ERROR; - } - - // MS_HYP_CHANGE BEGIN - if (IsIsolated()) { - // - // Canonicalize the VA. - // - Private->Buffer = NvmExpressGetSharedVa(Private->Buffer); - } - // MS_HYP_CHANGE END - - Private->BufferPciAddr = (UINT8 *)(UINTN)MappedAddr; - - // Disable the controller to wait for CSTS.RDY to become 0 - // NVMe Base Specification 2.0e, Section 3.5 Controller Initialization - // MU_CHANGE [END] - Allocate IO Queue Buffer - Status = NvmeDisableController (Private); - - if (EFI_ERROR (Status)) { - return Status; - } - - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - // - // Address of admin submission queue. - // - // MU_CHANGE - Remove the page mask since the buffer is allocated using AllocatePages - // Asq = (UINT64)(UINTN)(Private->BufferPciAddr); - - // - // Address of admin completion queue. - // - // MU_CHANGE - Remove the page mask since the buffer is allocated using AllocatePages - // Acq = (UINT64)(UINTN)(Private->BufferPciAddr + EFI_PAGE_SIZE); - - // - // Address of I/O submission & completion queue. - // - // ZeroMem (Private->Buffer, EFI_PAGES_TO_SIZE (6)); - // Private->SqBuffer[0] = (NVME_SQ *)(UINTN)(Private->Buffer); - // Private->SqBufferPciAddr[0] = (NVME_SQ *)(UINTN)(Private->BufferPciAddr); - // Private->CqBuffer[0] = (NVME_CQ *)(UINTN)(Private->Buffer + 1 * EFI_PAGE_SIZE); - // Private->CqBufferPciAddr[0] = (NVME_CQ *)(UINTN)(Private->BufferPciAddr + 1 * EFI_PAGE_SIZE); - // Private->SqBuffer[1] = (NVME_SQ *)(UINTN)(Private->Buffer + 2 * EFI_PAGE_SIZE); - // Private->SqBufferPciAddr[1] = (NVME_SQ *)(UINTN)(Private->BufferPciAddr + 2 * EFI_PAGE_SIZE); - // Private->CqBuffer[1] = (NVME_CQ *)(UINTN)(Private->Buffer + 3 * EFI_PAGE_SIZE); - // Private->CqBufferPciAddr[1] = (NVME_CQ *)(UINTN)(Private->BufferPciAddr + 3 * EFI_PAGE_SIZE); - // Private->SqBuffer[2] = (NVME_SQ *)(UINTN)(Private->Buffer + 4 * EFI_PAGE_SIZE); - // Private->SqBufferPciAddr[2] = (NVME_SQ *)(UINTN)(Private->BufferPciAddr + 4 * EFI_PAGE_SIZE); - // Private->CqBuffer[2] = (NVME_CQ *)(UINTN)(Private->Buffer + 5 * EFI_PAGE_SIZE); - // Private->CqBufferPciAddr[2] = (NVME_CQ *)(UINTN)(Private->BufferPciAddr + 5 * EFI_PAGE_SIZE); - - // DEBUG ((DEBUG_INFO, "Admin Submission Queue size (Aqa.Asqs) = [%08X]\n", Aqa.Asqs)); - // DEBUG ((DEBUG_INFO, "Admin Completion Queue size (Aqa.Acqs) = [%08X]\n", Aqa.Acqs)); - // DEBUG ((DEBUG_INFO, "Admin Submission Queue (SqBuffer[0]) = [%016X]\n", Private->SqBuffer[0])); - // DEBUG ((DEBUG_INFO, "Admin Completion Queue (CqBuffer[0]) = [%016X]\n", Private->CqBuffer[0])); - // DEBUG ((DEBUG_INFO, "Sync I/O Submission Queue (SqBuffer[1]) = [%016X]\n", Private->SqBuffer[1])); - // DEBUG ((DEBUG_INFO, "Sync I/O Completion Queue (CqBuffer[1]) = [%016X]\n", Private->CqBuffer[1])); - // DEBUG ((DEBUG_INFO, "Async I/O Submission Queue (SqBuffer[2]) = [%016X]\n", Private->SqBuffer[2])); - // DEBUG ((DEBUG_INFO, "Async I/O Completion Queue (CqBuffer[2]) = [%016X]\n", Private->CqBuffer[2])); - - // - // Program admin queue attributes. - // - Status = WriteNvmeAdminQueueAttributes (Private, &Aqa); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Program admin submission queue address. - // - // Status = WriteNvmeAdminSubmissionQueueBaseAddress (Private, &Asq); - - // - // Program admin completion queue address. - // - // Status = WriteNvmeAdminCompletionQueueBaseAddress (Private, &Acq); - - Status = NvmeControllerInitAdminQueues (Private); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = NvmeEnableController (Private, Private->SqData[0].EntrySize, Private->CqData[0].EntrySize); - if (EFI_ERROR (Status)) { - return Status; - } - - // MU_CHANGE [END] - Allocate IO Queue Buffer - - // - // Allocate buffer for Identify Controller data - // - if (Private->ControllerData == NULL) { - Private->ControllerData = (NVME_ADMIN_CONTROLLER_DATA *)AllocateZeroPool (sizeof (NVME_ADMIN_CONTROLLER_DATA)); - - if (Private->ControllerData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - // - // Get current Identify Controller Data - // - Status = NvmeIdentifyController (Private, Private->ControllerData); - - if (EFI_ERROR (Status)) { - FreePool (Private->ControllerData); - Private->ControllerData = NULL; - return EFI_NOT_FOUND; - } - - // - // Dump NvmExpress Identify Controller Data - // - // Serial Number and Model Number are not null-terminated strings, but will be printed as ones. - // So here we add a null terminator to the end of their arrays. - CopyMem (Sn, Private->ControllerData->Sn, sizeof (Private->ControllerData->Sn)); - Sn[20] = 0; - CopyMem (Mn, Private->ControllerData->Mn, sizeof (Private->ControllerData->Mn)); - Mn[40] = 0; - DEBUG ((DEBUG_INFO, " == NVME IDENTIFY CONTROLLER DATA ==\n")); - DEBUG ((DEBUG_INFO, " PCI VID : 0x%x\n", Private->ControllerData->Vid)); - DEBUG ((DEBUG_INFO, " PCI SSVID : 0x%x\n", Private->ControllerData->Ssvid)); - DEBUG ((DEBUG_INFO, " SN : %a\n", Sn)); - DEBUG ((DEBUG_INFO, " MN : %a\n", Mn)); - DEBUG ((DEBUG_INFO, " FR : 0x%x\n", *((UINT64 *)Private->ControllerData->Fr))); - DEBUG ((DEBUG_INFO, " TNVMCAP (high 8-byte) : 0x%lx\n", *((UINT64 *)(Private->ControllerData->Tnvmcap + 8)))); - DEBUG ((DEBUG_INFO, " TNVMCAP (low 8-byte) : 0x%lx\n", *((UINT64 *)Private->ControllerData->Tnvmcap))); - DEBUG ((DEBUG_INFO, " RAB : 0x%x\n", Private->ControllerData->Rab)); - DEBUG ((DEBUG_INFO, " IEEE : 0x%x\n", *(UINT32 *)Private->ControllerData->Ieee_oui)); - DEBUG ((DEBUG_INFO, " AERL : 0x%x\n", Private->ControllerData->Aerl)); - DEBUG ((DEBUG_INFO, " SQES : 0x%x\n", Private->ControllerData->Sqes)); - DEBUG ((DEBUG_INFO, " CQES : 0x%x\n", Private->ControllerData->Cqes)); - DEBUG ((DEBUG_INFO, " NN : 0x%x\n", Private->ControllerData->Nn)); - - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - // - // Send Set Features Command to request the maximum number of data queues. - // The controller is free to allocate a different number of queues from the number requested. - // The number of queues allocated is returned and stored in the controller private data structure - // using the NumberOfIoQueuePairs field. - // - Status = NvmeSetFeaturesNumberOfQueues (Private, NVME_MAX_QUEUES - 1); - - if (EFI_ERROR (Status)) { - return Status; - } - - // MU_CHANGE [END] - Request Number of Queues from Controller - - // MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - // - // Allocate Data Queues - note we are assuming the queue entry sizes are the same as the admin queue entry sizes for the sake of memory allocation. - // The identify controller data tells us in SQES and CQES what the controller's minimum and maximum queue entry sizes are. We haven't used this before since we - // use the spec-defined minimum queue entry sizes. - // We are also allocating based on the admin defined queue sizes in number of entries. - // Some scenarios may use different queue sizes, currently we only see the case where the driver needs IO queue sizes <= admin queue sizes. So this allocation should be sufficient. - // We may want to explore a more dynamic allocation in the future. - // - for (Index = 1; Index <= Private->NumberOfIoQueuePairs; Index++) { - Private->SqData[Index].NumberOfEntries = Private->SqData[0].NumberOfEntries; - Private->CqData[Index].NumberOfEntries = Private->CqData[0].NumberOfEntries; - Private->SqData[Index].EntrySize = Private->SqData[0].EntrySize; - Private->CqData[Index].EntrySize = Private->CqData[0].EntrySize; - } - - // Using the first data queue size for the number of pages required for the data queues - IoQueuePairPageCount = NVME_SQ_SIZE_IN_PAGES (Private, 1) + NVME_CQ_SIZE_IN_PAGES (Private, 1); - - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - IoQueuePairPageCount * Private->NumberOfIoQueuePairs, - (VOID **)&Private->IoQueueBuffer, - 0 - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // MS_HYP_CHANGE BEGIN - if (IsIsolated ()) { - Status = NvmExpressMakeAddressRangeShared ( - &Private->IoQueueVisibilityContext, - Private->IoQueueBuffer, - (UINT32)IoQueuePairPageCount * Private->NumberOfIoQueuePairs * EFI_PAGE_SIZE - ); - - if (EFI_ERROR (Status)) { - EFI_STATUS FreeStatus = PciIo->FreeBuffer (PciIo, IoQueuePairPageCount*Private->NumberOfIoQueuePairs, Private->IoQueueBuffer); - - if (EFI_ERROR (FreeStatus)) { - DEBUG ((DEBUG_ERROR, "%a: FreeBuffer IoQueueBuffer failed %r\n", __func__, FreeStatus)); - ASSERT_EFI_ERROR (FreeStatus); - } - - Private->IoQueueBuffer = NULL; - return Status; - } - } - // MS_HYP_CHANGE END - - Bytes = EFI_PAGES_TO_SIZE (IoQueuePairPageCount * Private->NumberOfIoQueuePairs); - Status = PciIo->Map ( - PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - Private->IoQueueBuffer, - &Bytes, - &MappedAddr, - &Private->IoQueueMapping - ); - - if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (IoQueuePairPageCount * Private->NumberOfIoQueuePairs))) { - return EFI_DEVICE_ERROR; - } - - - // MS_HYP_CHANGE BEGIN - if (IsIsolated()) { - // - // Canonicalize the VA. - // - Private->IoQueueBuffer = NvmExpressGetSharedVa(Private->IoQueueBuffer); - } - // MS_HYP_CHANGE END - - - Private->IoQueueBufferPciAddr = (UINT8 *)(UINTN)MappedAddr; - - Status = NvmeControllerInitIoQueues (Private); - // MU_CHANGE [END] - Allocate IO Queue Buffer - - return Status; -} - -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - -/** - Reset the Nvm Express controller. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS The NVM Express Controller is reset successfully. - @retval Others A device error occurred while resetting the controller. - -**/ -EFI_STATUS -NvmeControllerReset ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT32 Index; - UINT16 VidDid[2]; - UINT8 Sn[21]; - UINT8 Mn[41]; - NVME_AQA Aqa; - UINT32 NdqpBeforeReset; - - DEBUG ((DEBUG_INFO, "%a: Begin Controller Reset\n", __func__)); - - PciIo = Private->PciIo; - - // - // Verify the controller is still accessible - // - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - PCI_VENDOR_ID_OFFSET, - ARRAY_SIZE (VidDid), - VidDid - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return EFI_DEVICE_ERROR; - } - - if ((VidDid[0] == NVME_INVALID_VID_DID) || (VidDid[1] == NVME_INVALID_VID_DID)) { - return EFI_DEVICE_ERROR; - } - - for (Index = 0; Index < NVME_MAX_QUEUES; Index++) { - Private->Cid[Index] = 0; - Private->Pt[Index] = 0; - Private->SqTdbl[Index].Sqt = 0; - Private->CqHdbl[Index].Cqh = 0; - } - - Private->AsyncSqHead = 0; - - Status = NvmeDisableController (Private); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = ReadNvmeAdminQueueAttributes (Private, &Aqa); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((Private->SqData[0].NumberOfEntries != Aqa.Asqs) || (Private->CqData[0].NumberOfEntries != Aqa.Acqs)) { - // By spec these values should not change between resets, so we'll fail out here. - DEBUG ((DEBUG_ERROR, "%a: Admin Submission Queue Size (Number of Entries) mismatch: %d != %d\n", __func__, Private->SqData[0].NumberOfEntries, Aqa.Asqs)); - ASSERT (FALSE); - return EFI_DEVICE_ERROR; - } - - Status = NvmeControllerInitAdminQueues (Private); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = NvmeEnableController (Private, Private->SqData[0].EntrySize, Private->CqData[0].EntrySize); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Allocate buffer for Identify Controller data - // - if (Private->ControllerData == NULL) { - Private->ControllerData = (NVME_ADMIN_CONTROLLER_DATA *)AllocateZeroPool (sizeof (NVME_ADMIN_CONTROLLER_DATA)); - - if (Private->ControllerData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - // - // Get current Identify Controller Data - // - Status = NvmeIdentifyController (Private, Private->ControllerData); - - if (EFI_ERROR (Status)) { - FreePool (Private->ControllerData); - Private->ControllerData = NULL; - return EFI_NOT_FOUND; - } - - // - // Dump NvmExpress Identify Controller Data - // - CopyMem (Sn, Private->ControllerData->Sn, sizeof (Private->ControllerData->Sn)); - // Serial Number and Model Number are not null-terminated strings, but will be printed as ones. - // So here we add a null terminator to the end of their arrays. - Sn[20] = 0; - CopyMem (Mn, Private->ControllerData->Mn, sizeof (Private->ControllerData->Mn)); - Mn[40] = 0; - DEBUG ((DEBUG_INFO, " == NVME IDENTIFY CONTROLLER DATA ==\n")); - DEBUG ((DEBUG_INFO, " PCI VID : 0x%x\n", Private->ControllerData->Vid)); - DEBUG ((DEBUG_INFO, " PCI SSVID : 0x%x\n", Private->ControllerData->Ssvid)); - DEBUG ((DEBUG_INFO, " SN : %a\n", Sn)); - DEBUG ((DEBUG_INFO, " MN : %a\n", Mn)); - DEBUG ((DEBUG_INFO, " FR : 0x%x\n", *((UINT64 *)Private->ControllerData->Fr))); - DEBUG ((DEBUG_INFO, " TNVMCAP (high 8-byte) : 0x%lx\n", *((UINT64 *)(Private->ControllerData->Tnvmcap + 8)))); - DEBUG ((DEBUG_INFO, " TNVMCAP (low 8-byte) : 0x%lx\n", *((UINT64 *)Private->ControllerData->Tnvmcap))); - DEBUG ((DEBUG_INFO, " RAB : 0x%x\n", Private->ControllerData->Rab)); - DEBUG ((DEBUG_INFO, " IEEE : 0x%x\n", *(UINT32 *)Private->ControllerData->Ieee_oui)); - DEBUG ((DEBUG_INFO, " AERL : 0x%x\n", Private->ControllerData->Aerl)); - DEBUG ((DEBUG_INFO, " SQES : 0x%x\n", Private->ControllerData->Sqes)); - DEBUG ((DEBUG_INFO, " CQES : 0x%x\n", Private->ControllerData->Cqes)); - DEBUG ((DEBUG_INFO, " NN : 0x%x\n", Private->ControllerData->Nn)); - - // - // Send Set Features Command to request the maximum number of data queues. - // The controller is free to allocate a different number of queues from the number requested. - // The number of queues allocated is returned and stored in the controller private data structure - // using the NumberOfIoQueuePairs field. - // - NdqpBeforeReset = Private->NumberOfIoQueuePairs; - Status = NvmeSetFeaturesNumberOfQueues (Private, NVME_MAX_QUEUES - 1); - if (EFI_ERROR (Status)) { - return Status; - } - - if (NdqpBeforeReset != Private->NumberOfIoQueuePairs) { - // This is a controller reset, so the number of data queues should not have changed. - // If the number of queues has changed, then the driver must be re-initialized. - DEBUG ((DEBUG_ERROR, "%a: Number of Data Queue Pairs mismatch: %d != %d\n", __func__, NdqpBeforeReset, Private->NumberOfIoQueuePairs)); - ASSERT (FALSE); - return EFI_DEVICE_ERROR; - } - - // - // Create I/O completion queue(s). - // - Status = NvmeControllerInitIoQueues (Private); - if (EFI_ERROR (Status)) { - return Status; - } - - return Status; -} - -// MU_CHANGE [END] - Allocate IO Queue Buffer - -/** - This routine is called to properly shutdown the Nvm Express controller per NVMe spec. - - @param[in] ResetType The type of reset to perform. - @param[in] ResetStatus The status code for the reset. - @param[in] DataSize The size, in bytes, of ResetData. - @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or - EfiResetShutdown the data buffer starts with a Null-terminated - string, optionally followed by additional binary data. - The string is a description that the caller may use to further - indicate the reason for the system reset. - For a ResetType of EfiResetPlatformSpecific the data buffer - also starts with a Null-terminated string that is followed - by an EFI_GUID that describes the specific type of reset to perform. -**/ -VOID -EFIAPI -NvmeShutdownAllControllers ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_HANDLE *Handles; - UINTN HandleCount; - UINTN HandleIndex; - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfos; - UINTN OpenInfoCount; - UINTN OpenInfoIndex; - EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *NvmePassThru; - NVME_CC Cc; - NVME_CSTS Csts; - UINTN Index; - NVME_CONTROLLER_PRIVATE_DATA *Private; - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleCount, - &Handles - ); - if (EFI_ERROR (Status)) { - HandleCount = 0; - } - - for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { - Status = gBS->OpenProtocolInformation ( - Handles[HandleIndex], - &gEfiPciIoProtocolGuid, - &OpenInfos, - &OpenInfoCount - ); - if (EFI_ERROR (Status)) { - continue; - } - - for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) { - // - // Find all the NVME controller managed by this driver. - // gImageHandle equals to DriverBinding handle for this driver. - // - if (((OpenInfos[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) && - (OpenInfos[OpenInfoIndex].AgentHandle == gImageHandle)) - { - Status = gBS->OpenProtocol ( - OpenInfos[OpenInfoIndex].ControllerHandle, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **)&NvmePassThru, - NULL, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - continue; - } - - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (NvmePassThru); - - // - // Read Controller Configuration Register. - // - Status = ReadNvmeControllerConfiguration (Private, &Cc); - if (EFI_ERROR (Status)) { - continue; - } - - // - // The host should set the Shutdown Notification (CC.SHN) field to 01b - // to indicate a normal shutdown operation. - // - Cc.Shn = NVME_CC_SHN_NORMAL_SHUTDOWN; - Status = WriteNvmeControllerConfiguration (Private, &Cc); - if (EFI_ERROR (Status)) { - continue; - } - - // - // The controller indicates when shutdown processing is completed by updating the - // Shutdown Status (CSTS.SHST) field to 10b. - // Wait up to 45 seconds (break down to 4500 x 10ms) for the shutdown to complete. - // - for (Index = 0; Index < NVME_SHUTDOWN_PROCESS_TIMEOUT * 100; Index++) { - Status = ReadNvmeControllerStatus (Private, &Csts); - if (!EFI_ERROR (Status) && (Csts.Shst == NVME_CSTS_SHST_SHUTDOWN_COMPLETED)) { - DEBUG ((DEBUG_INFO, "NvmeShutdownController: shutdown processing is completed after %dms.\n", Index * 10)); - break; - } - - // - // Stall for 10ms - // - gBS->Stall (10 * 1000); - } - - if (Index == NVME_SHUTDOWN_PROCESS_TIMEOUT * 100) { - DEBUG ((DEBUG_ERROR, "NvmeShutdownController: shutdown processing is timed out\n")); - } - } - } - } -} - -/** - Register the shutdown notification through the ResetNotification protocol. - - Register the shutdown notification when mNvmeControllerNumber increased from 0 to 1. -**/ -VOID -NvmeRegisterShutdownNotification ( - VOID - ) -{ - EFI_STATUS Status; - EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify; - - mNvmeControllerNumber++; - if (mNvmeControllerNumber == 1) { - Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **)&ResetNotify); - if (!EFI_ERROR (Status)) { - Status = ResetNotify->RegisterResetNotify (ResetNotify, NvmeShutdownAllControllers); - ASSERT_EFI_ERROR (Status); - } else { - DEBUG ((DEBUG_WARN, "NVME: ResetNotification absent! Shutdown notification cannot be performed!\n")); - } - } -} - -/** - Unregister the shutdown notification through the ResetNotification protocol. - - Unregister the shutdown notification when mNvmeControllerNumber decreased from 1 to 0. -**/ -VOID -NvmeUnregisterShutdownNotification ( - VOID - ) -{ - EFI_STATUS Status; - EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify; - - mNvmeControllerNumber--; - if (mNvmeControllerNumber == 0) { - Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **)&ResetNotify); - if (!EFI_ERROR (Status)) { - Status = ResetNotify->UnregisterResetNotify (ResetNotify, NvmeShutdownAllControllers); - ASSERT_EFI_ERROR (Status); - } - } -} diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressHci.h b/MsvmPkg/NvmExpressDxe/NvmExpressHci.h deleted file mode 100644 index 4027616e69..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressHci.h +++ /dev/null @@ -1,107 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - (C) Copyright 2016 Hewlett Packard Enterprise Development LP
- Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _NVME_HCI_H_ -#define _NVME_HCI_H_ - -#define NVME_BAR 0 - -// -// Offset from the beginning of private data queue buffer -// -#define NVME_ASQ_BUF_OFFSET EFI_PAGE_SIZE - -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - -/** - Reset the Nvm Express controller. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS The NVM Express Controller is reset successfully. - @retval Others A device error occurred while resetting the controller. - -**/ -EFI_STATUS -NvmeControllerReset ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ); - -// MU_CHANGE [END] - Allocate IO Queue Buffer - -/** - Initialize the Nvm Express controller. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS The NVM Express Controller is initialized successfully. - @retval Others A device error occurred while initializing the controller. - -**/ -EFI_STATUS -NvmeControllerInit ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ); - -/** - Get identify controller data. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Buffer The buffer used to store the identify controller data. - - @return EFI_SUCCESS Successfully get the identify controller data. - @return EFI_DEVICE_ERROR Fail to get the identify controller data. - -**/ -EFI_STATUS -NvmeIdentifyController ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN VOID *Buffer - ); - -/** - Get specified identify namespace data. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param NamespaceId The specified namespace identifier. - @param Buffer The buffer used to store the identify namespace data. - - @return EFI_SUCCESS Successfully get the identify namespace data. - @return EFI_DEVICE_ERROR Fail to get the identify namespace data. - -**/ -EFI_STATUS -NvmeIdentifyNamespace ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT32 NamespaceId, - IN VOID *Buffer - ); - -// MU_CHANGE [BEGIN] - Allocate IO Queue Buffer - -/** - Read Nvm Express admin queue attributes register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Aqa The buffer used to store the content to be read from admin queue attributes register. - - @return EFI_SUCCESS Successfully read data from the admin queue attributes register. - @return EFI_DEVICE_ERROR Fail to read data from the admin queue attributes register. - -**/ -EFI_STATUS -ReadNvmeAdminQueueAttributes ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - OUT NVME_AQA *Aqa - ); - -// MU_CHANGE [END] - Allocate IO Queue Buffer - -#endif diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressMediaSanitize.c b/MsvmPkg/NvmExpressDxe/NvmExpressMediaSanitize.c deleted file mode 100644 index dd24c2c339..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressMediaSanitize.c +++ /dev/null @@ -1,584 +0,0 @@ -/** @file -- NvmExpressMediaSanitize.c - This driver will implement sanitize operations on all NVMe mass storage devices - based on NIST purge and clear operations. These operations will then be mapped to - one of two NVMe admin commands: - - -Format NVM - -Sanitize - - Implementation based off NVMe spec revision 1.4c. - - Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "NvmExpress.h" - -/** - Send NVM Express FormatNVM Admin Command - - The Format NVM command is used to low level format the NVM media. This command is used by - the host to change the LBA data size and/or metadata size. - - A low level format may destroy all data and metadata associated with all namespaces or only - the specific namespace associated with the command (refer to the Format NVM Attributes field - in the Identify Controller data structure). - - After the Format NVM command successfully completes, the controller shall not return any user - data that was previously contained in an affected namespace. - - @param[in] This Indicates a pointer to the calling context (Block IO Protocol) - @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be - allocated and built. Caller must set the NamespaceId to zero if the - device path node will contain a valid UUID. - @param[in] Ses Secure Erase Setting (SES) value - - 000b: No secure erase operation requested - - 001b: User Data Erase - - 010b: Cryptographic Erase - - 011b to 111b: Reserved - @param[in] Flbas New LBA size (in terms of LBA Format size Index (bits 3:0) in NamespaceData). - If this param is 0 (NULL), then use existing LBA size. - - @retval EFI_SUCCESS The device formatted correctly. - @retval EFI_WRITE_PROTECTED The device can not be formatted due to write protection. - @retval EFI_DEVICE_ERROR The device reported an error while performing the format. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_INVALID_PARAMETER The format request contains parameters that are not valid. - - **/ -EFI_STATUS -NvmExpressFormatNvm ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 NamespaceId, - IN UINT32 Ses, - IN UINT32 Flbas - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - NVME_ADMIN_FORMAT_NVM FormatNvmCdw10; - NVME_ADMIN_NAMESPACE_DATA *NewNamespaceData; - UINT32 Lbads; - UINT32 NewFlbas; - UINT32 LbaFmtIdx; - EFI_STATUS Status; - UINT32 LbaFormat; - UINT16 StatusField; - UINT16 Sct; - UINT16 Sc; - - Status = EFI_NOT_STARTED; - LbaFormat = 0; - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - ZeroMem (&FormatNvmCdw10, sizeof (NVME_ADMIN_FORMAT_NVM)); - - NewNamespaceData = NULL; - Lbads = 0; - NewFlbas = 0; - LbaFmtIdx = 0; - StatusField = 0; - Sct = 0; - Sc = 0; - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - Command.Cdw0.Opcode = NVME_ADMIN_FORMAT_NVM_CMD; - Command.Nsid = NamespaceId; - - // - // SES (Secure Erase Settings) - // - FormatNvmCdw10.Ses = Ses; - - // - // Change LBA size/format if LbaFormat param != NULL, otherwise keep same LBA format. - // Current supported LBA format size in Identify Namespace LBA Format Table, indexed by - // FLBAS (bits 3:0). - // - LbaFormat = (Flbas == 0 ? Device->NamespaceData.Flbas : Flbas); - FormatNvmCdw10.Lbaf = LbaFormat & NVME_LBA_FORMATNVM_LBAF_MASK; - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &FormatNvmCdw10, sizeof (NVME_ADMIN_FORMAT_NVM)); - - // - // Send Format NVM command via passthru and wait for completion - // - // If LBA size changed successfully, then update private data structures and Block IO - // and Media protocols to reflect new LBA size. - // - Status = Device->Controller->Passthru.PassThru ( - &(Device->Controller->Passthru), - NamespaceId, - &CommandPacket, - NULL - ); - - if (EFI_ERROR (Status)) { - StatusField = (UINT16)((CommandPacket.NvmeCompletion->DW3 & NVME_CQE_STATUS_FIELD_MASK) >> - NVME_CQE_STATUS_FIELD_OFFSET); - - Sc = (StatusField & NVME_CQE_STATUS_FIELD_SC_MASK) >> NVME_CQE_STATUS_FIELD_SC_OFFSET; - Sct = (StatusField & NVME_CQE_STATUS_FIELD_SCT_MASK) >> NVME_CQE_STATUS_FIELD_SCT_OFFSET; - - DEBUG ((DEBUG_ERROR, "%a: NVMe FormatNVM admin command failed SCT = 0x%x, SC = 0x%x\n", __func__, Sct, Sc)); - } else { - // - // Update Block IO and Media Protocols only if Flbas parameter was not NULL. - // Call Identify Namespace again and update all protocols fields and local - // cached copies of fields related to block size. - // - if (Flbas != 0) { - NewNamespaceData = AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA)); - if (NewNamespaceData == NULL) { - Status = EFI_OUT_OF_RESOURCES; - } else { - Status = NvmeIdentifyNamespace ( - Device->Controller, - NamespaceId, - (VOID *)NewNamespaceData - ); - - if (!EFI_ERROR (Status)) { - // - // Update all fields related to LBA size, allocation, and alignment - // - NewFlbas = NewNamespaceData->Flbas; - LbaFmtIdx = NewFlbas & NVME_LBA_FORMATNVM_LBAF_MASK; - Lbads = NewNamespaceData->LbaFormat[LbaFmtIdx].Lbads; - Device->Media.BlockSize = (UINT32)1 << Lbads; - Device->Media.LastBlock = NewNamespaceData->Nsze - 1; - - CopyMem (&Device->NamespaceData, NewNamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA)); - } - } - } - } - - return Status; -} - -/** - Send NVM Express Sanitize Admin Command - - The Sanitize command is used to start a sanitize operation or to recover from a previously - failed sanitize operation. The sanitize operation types that may be supported are Block - Erase, Crypto Erase, and Overwrite. - - All sanitize operations are processed in the background (i.e., completion of the Sanitize - command does not indicate completion of the sanitize operation). - - @param[in] This Indicates a pointer to the calling context (Block IO Protocol) - @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be - allocated and built. Caller must set the NamespaceId to zero if the - device path node will contain a valid UUID. - @param[in] SanitizeAction Sanitize action - @param[in] NoDeallocAfterSanitize No deallocate after sanitize option - @param[in] OverwritePattern Pattern to overwrite old user data - - @retval EFI_SUCCESS The media was sanitized successfully on the device. - @retval EFI_WRITE_PROTECTED The device can not be sanitized due to write protection. - @retval EFI_DEVICE_ERROR The device reported an error while performing the sanitize. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device. - @retval EFI_INVALID_PARAMETER The sanitize request contains parameters that are not valid. - - **/ -EFI_STATUS -NvmExpressSanitize ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 NamespaceId, - IN UINT32 SanitizeAction, - IN UINT32 NoDeallocAfterSanitize, - IN UINT32 OverwritePattern - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - NVME_ADMIN_SANITIZE SanitizeCdw10Cdw11; - EFI_STATUS Status; - UINT16 StatusField; - UINT16 Sct; - UINT16 Sc; - UINT32 FnvmSes; - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - ZeroMem (&SanitizeCdw10Cdw11, sizeof (NVME_ADMIN_SANITIZE)); - - StatusField = 0; - Sct = 0; - Sc = 0; - FnvmSes = 0; - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - Command.Cdw0.Opcode = NVME_ADMIN_SANITIZE_CMD; - Command.Nsid = NamespaceId; - - SanitizeCdw10Cdw11.Nodas = NoDeallocAfterSanitize; - SanitizeCdw10Cdw11.Sanact = SanitizeAction; - SanitizeCdw10Cdw11.Ovrpat = OverwritePattern; - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &SanitizeCdw10Cdw11, sizeof (NVME_ADMIN_SANITIZE)); - - // - // Send Format NVM command via passthru and wait for completion - // - Status = Device->Controller->Passthru.PassThru ( - &(Device->Controller->Passthru), - NamespaceId, - &CommandPacket, - NULL - ); - - if (EFI_ERROR (Status)) { - StatusField = (UINT16)((CommandPacket.NvmeCompletion->DW3 & NVME_CQE_STATUS_FIELD_MASK) >> - NVME_CQE_STATUS_FIELD_OFFSET); - - Sc = (StatusField & NVME_CQE_STATUS_FIELD_SC_MASK) >> NVME_CQE_STATUS_FIELD_SC_OFFSET; - Sct = (StatusField & NVME_CQE_STATUS_FIELD_SCT_MASK) >> NVME_CQE_STATUS_FIELD_SCT_OFFSET; - - DEBUG ((DEBUG_ERROR, "%a: NVMe Sanitize admin command failed SCT = 0x%x, SC = 0x%x\n", __func__, Sct, Sc)); - - // - // Check for an error status code of "Invalid Command Opcode" in case - // the NVM Express controller does not support Sanitize. If the NVM - // Exress Controller does not support Sanitize, then send a Format NVM - // admin command instead to perform the Purge operation. - // - if ((Sct == NVME_CQE_SCT_GENERIC_CMD_STATUS) && - (Sc == NVME_CQE_SC_INVALID_CMD_OPCODE)) - { - switch (SanitizeCdw10Cdw11.Sanact) { - case SANITIZE_ACTION_BLOCK_ERASE: - FnvmSes = SES_USER_DATA_ERASE; // User Data Erase (LBAs indeterminate after) - break; - case SANITIZE_ACTION_CRYPTO_ERASE: - FnvmSes = SES_CRYPTO_ERASE; // Crypto Erase - break; - case SANITIZE_ACTION_OVERWRITE: - case SANITIZE_ACTION_EXIT_FAILURE_MODE: - default: - // - // Cannot perform an equivalent FormatNVM action/operation - // - FnvmSes = SES_NO_SECURE_ERASE; - break; - } - - if ((FnvmSes == SES_USER_DATA_ERASE) || (FnvmSes == SES_CRYPTO_ERASE)) { - Status = NvmExpressFormatNvm ( - This, - NVME_ALL_NAMESPACES, - FnvmSes, - 0 // Pass in NULL so existing LBA size is used in Format NVM - ); - } - } - } - - return Status; -} - -/** - Clear Media utilizes transport native WRITE commands to write a fixed pattern - of non-sensitive data to the media. - - NOTE: The caller shall send buffer of one sector/LBA size with overwrite data. - NOTE: This operation is a blocking call. - NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. - - Functions are defined to erase and purge data at a block level from mass - storage devices as well as to manage such devices in the EFI boot services - environment. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the write request is for. - @param[in] PassCount The number of passes to write over media. - @param[in] SectorOwBuffer A pointer to the overwrite buffer. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -NvmExpressMediaClear ( - IN MEDIA_SANITIZE_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT32 PassCount, - IN VOID *SectorOwBuffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_BLOCK_IO_MEDIA *Media; - EFI_LBA SectorOffset; - UINT32 TotalPassCount; - EFI_STATUS Status; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE (This); - Media = &Device->Media; - SectorOffset = 0; - - if ((MediaId != Media->MediaId) || (!Media->MediaPresent)) { - return EFI_MEDIA_CHANGED; - } - - // - // If an invalid buffer or buffer size is sent, the Media Clear operation - // cannot be performed as it requires a native WRITE command. The overwrite - // buffer must have granularity of a namespace block size. - // - if (SectorOwBuffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = EFI_SUCCESS; - - // - // Per NIST 800-88r1, one or more pass of writes may be alteratively used. - // - for (TotalPassCount = 0; TotalPassCount < PassCount; TotalPassCount++) { - for (SectorOffset = 0; SectorOffset < Media->LastBlock; SectorOffset++ ) { - Status = Device->BlockIo.WriteBlocks ( - &Device->BlockIo, - MediaId, - SectorOffset, // Sector/LBA offset (increment each pass) - 1, // Write one sector per write - SectorOwBuffer // overwrite buffer - ); - } - - // - // Reset SectorOffset back to zero if another pass on namespace is needed - // - SectorOffset = 0; - } - - return Status; -} - -/** - Purge Media utilizes transport native Sanitize operations. Sanitize specific - purge actions include: overwrite, block erase, or crypto erase. - - Functions are defined to erase and purge data at a block level from mass - storage devices as well as to manage such devices in the EFI boot services - environment. Sanitization refers to a process that renders access to target - data on the media infeasible for a given level of effort. - - NOTE: This operation is a blocking call. - NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the write request is for. - @param[in] PurgeAction The purage action (overwrite, crypto erase, block erase). - @param[in] OverwritePattern 32-bit pattern to overwrite on media (for overwrite). - - @retval EFI_SUCCESS The media was purged successfully on the device. - @retval EFI_WRITE_PROTECTED The device can not be purged due to write protection. - @retval EFI_DEVICE_ERROR The device reported an error while performing the purge. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device. - @retval EFI_INVALID_PARAMETER The purge request contains parameters that are not valid. - -**/ -EFI_STATUS -EFIAPI -NvmExpressMediaPurge ( - IN MEDIA_SANITIZE_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT32 PurgeAction, - IN UINT32 OverwritePattern - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_BLOCK_IO_MEDIA *Media; - NVME_SANICAP SaniCap; - UINT32 SanitizeAction; - UINT32 NoDeallocate; - UINT32 NamespaceId; - EFI_STATUS Status; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE (This); - NamespaceId = Device->NamespaceId; - Media = &Device->Media; - SaniCap = Device->Controller->ControllerData->Sanicap; - NoDeallocate = 0; - - if ((MediaId != Media->MediaId) || (!Media->MediaPresent)) { - return EFI_MEDIA_CHANGED; - } - - // - // Purge action will directly map to sanitize action. If no valid purge - // action is selected, then default to no action and let the NVMe SSD handle - // the no-op sanitize action (as there may be other contingencies). - // - if (((PurgeAction & PURGE_ACTION_OVERWRITE) == PURGE_ACTION_OVERWRITE) && (SaniCap.Ows)) { - SanitizeAction = SANITIZE_ACTION_OVERWRITE; - } else if (((PurgeAction & PURGE_ACTION_BLOCK_ERASE) == PURGE_ACTION_BLOCK_ERASE) && (SaniCap.Bes)) { - SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE; - } else if (((PurgeAction & PURGE_ACTION_CRYPTO_ERASE) == PURGE_ACTION_CRYPTO_ERASE) && (SaniCap.Ces)) { - SanitizeAction = SANITIZE_ACTION_CRYPTO_ERASE; - } else { - SanitizeAction = SANITIZE_ACTION_NO_ACTION; - } - - if ((PurgeAction & PURGE_ACTION_NO_DEALLOCATE) == PURGE_ACTION_NO_DEALLOCATE) { - NoDeallocate = NVME_NO_DEALLOCATE_AFTER_SANITZE; - } - - // - // Call NVM Express Admin command Sanitize (blocking call). - // - Status = NvmExpressSanitize ( - &Device->BlockIo, - NamespaceId, - SanitizeAction, - NoDeallocate, - OverwritePattern - ); - - return Status; -} - -/** - Format Media utilizes native format operations to modify sector/LBA size. - Secure erase actions are used to define how latent user data is erased. - - NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the clear request is for. - @param[in] LbaSize Size of LBA (in terms of power of two: 2^n). - @param[in] SecureEraseAction Secure erase action, if any, to apply to format. - - 000b: No secure erase operation requested - - 001b: User Data Erase - - 010b: Cryptographic Erase - - 011b to 111b: Reserved - - @retval EFI_SUCCESS The media format request comopleted successfully on the device. - @retval EFI_WRITE_PROTECTED The device can't be formatted due to write protection. - @retval EFI_DEVICE_ERROR The device reported an error while attempting to perform the format operation. - @retval EFI_INVALID_PARAMETER The format request contains parameters that are not valid. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - - **/ -EFI_STATUS -EFIAPI -NvmExpressMediaFormat ( - IN MEDIA_SANITIZE_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT32 LbaSize, - IN UINT32 SecureEraseAction - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_BLOCK_IO_MEDIA *Media; - UINT32 NamespaceId; - UINT32 SecureEraseSettings; - UINT32 FlbaIndex; - BOOLEAN LbaSizeIsSupported; - EFI_STATUS Status; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE (This); - NamespaceId = Device->NamespaceId; - Media = &Device->Media; - SecureEraseSettings = FORMAT_SES_NO_SECURE_ERASE_REQUESTED; - FlbaIndex = 0; - - if ((MediaId != Media->MediaId) || (!Media->MediaPresent)) { - return EFI_MEDIA_CHANGED; - } - - // - // Convert secure erase action to NVMe secure erase setting - // - switch (SecureEraseAction) { - case FORMAT_SES_USER_DATA_ERASE: - SecureEraseSettings = SES_USER_DATA_ERASE; - break; - case FORMAT_SES_CRYPTOGRAPHIC_ERASE: - SecureEraseSettings = SES_CRYPTO_ERASE; - break; - case FORMAT_SES_NO_SECURE_ERASE_REQUESTED: - default: - // - // Cannot perform an equivalent FormatNVM action/operation - // - SecureEraseSettings = SES_NO_SECURE_ERASE; - break; - } - - // - // The requested LBA size must be supported by the NVMe SSD as defined in Identify - // Namespace structure. - // - // Current supported LBA format sizes is in Identify Namespace LBA Format Table, - // indexed by FLBAS (bits 3:0). Loop through all supported LBADF sizes and check - // to see if requested LBA size is supported. If yes, send FormatNVM command. - // - LbaSizeIsSupported = FALSE; - for (FlbaIndex = 0; FlbaIndex < Device->NamespaceData.Nlbaf; FlbaIndex++) { - if (Device->NamespaceData.LbaFormat[FlbaIndex].Lbads == LbaSize) { - LbaSizeIsSupported = TRUE; - break; - } - } - - if (LbaSizeIsSupported) { - Status = NvmExpressFormatNvm ( - &Device->BlockIo, - NamespaceId, - SecureEraseSettings, - FlbaIndex - ); - } else { - Status = EFI_INVALID_PARAMETER; - } - - return Status; -} diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressMediaSanitize.h b/MsvmPkg/NvmExpressDxe/NvmExpressMediaSanitize.h deleted file mode 100644 index 197b923977..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressMediaSanitize.h +++ /dev/null @@ -1,191 +0,0 @@ -/** @file - Header file for MEDIA_SANITIZE_PROTOCOL interface. - - Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef NVME_MEDIA_SANITIZE_H_ -#define NVME_MEDIA_SANITIZE_H_ - -#define NVME_NO_DEALLOCATE_AFTER_SANITZE 0x1 - -/** - Send NVM Express FormatNVM Admin Command - - The Format NVM command is used to low level format the NVM media. This command is used by - the host to change the LBA data size and/or metadata size. - - A low level format may destroy all data and metadata associated with all namespaces or only - the specific namespace associated with the command (refer to the Format NVM Attributes field - in the Identify Controller data structure). - - After the Format NVM command successfully completes, the controller shall not return any user - data that was previously contained in an affected namespace. - - @param[in] This Indicates a pointer to the calling context (Block IO Protocol) - @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be - allocated and built. Caller must set the NamespaceId to zero if the - device path node will contain a valid UUID. - @param[in] Ses Secure Erase Setting (SES) value - - 000b: No secure erase operation requested - - 001b: User Data Erase - - 010b: Cryptographic Erase - - 011b to 111b: Reserved - @param[in] Flbas New LBA size (in terms of LBA Format size Index (bits 3:0) in NamespaceData). - If this param is 0 (NULL), then use existing LBA size. - - @retval EFI_SUCCESS The device formatted correctly. - @retval EFI_WRITE_PROTECTED The device can not be formatted due to write protection. - @retval EFI_DEVICE_ERROR The device reported an error while performing the format. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_INVALID_PARAMETER The format request contains parameters that are not valid. - -**/ -EFI_STATUS -NvmExpressFormatNvm ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 NamespaceId, - IN UINT32 Ses, - IN UINT32 Flbas - ); - -/** - Send NVM Express Sanitize Admin Command - - The Sanitize command is used to start a sanitize operation or to recover from a previously - failed sanitize operation. The sanitize operation types that may be supported are Block - Erase, Crypto Erase, and Overwrite. - - All sanitize operations are processed in the background (i.e., completion of the Sanitize - command does not indicate completion of the sanitize operation). - - @param[in] This Indicates a pointer to the calling context (Block IO Protocol) - @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be - allocated and built. Caller must set the NamespaceId to zero if the - device path node will contain a valid UUID. - @param[in] SanitizeAction Sanitize action - @param[in] NoDeallocAfterSanitize No deallocate after sanitize option - @param[in] OverwritePattern Pattern to overwrite old user data - - @retval EFI_SUCCESS The media was sanitized successfully on the device. - @retval EFI_WRITE_PROTECTED The device can not be sanitized due to write protection. - @retval EFI_DEVICE_ERROR The device reported an error while performing the sanitize. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device. - @retval EFI_INVALID_PARAMETER The sanitize request contains parameters that are not valid. - -**/ -EFI_STATUS -NvmExpressSanitize ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 NamespaceId, - IN UINT32 SanitizeAction, - IN UINT32 NoDeallocAfterSanitize, - IN UINT32 OverwritePattern - ); - -/** - Clear Media utilizes transport native WRITE commands to write a fixed pattern - of non-sensitive data to the media. - - NOTE: The caller shall send buffer of one sector/LBA size with overwrite data. - NOTE: This operation is a blocking call. - NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. - - Functions are defined to erase and purge data at a block level from mass - storage devices as well as to manage such devices in the EFI boot services - environment. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the write request is for. - @param[in] PassCount The number of passes to write over media. - @param[in] SectorOwBuffer A pointer to the overwrite buffer. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -NvmExpressMediaClear ( - IN MEDIA_SANITIZE_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT32 PassCount, - IN VOID *SectorOwBuffer - ); - -/** - Purge Media utilizes transport native Sanitize operations. Sanitize specific - purge actions include: overwrite, block erase, or crypto erase. - - Functions are defined to erase and purge data at a block level from mass - storage devices as well as to manage such devices in the EFI boot services - environment. Sanitization refers to a process that renders access to target - data on the media infeasible for a given level of effort. - - NOTE: This operation is a blocking call. - NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the write request is for. - @param[in] PurgeAction The purage action (overwrite, crypto erase, block erase). - @param[in] OverwritePattern 32-bit pattern to overwrite on media (for overwrite). - - @retval EFI_SUCCESS The media was purged successfully on the device. - @retval EFI_WRITE_PROTECTED The device can not be purged due to write protection. - @retval EFI_DEVICE_ERROR The device reported an error while performing the purge. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device. - @retval EFI_INVALID_PARAMETER The purge request contains parameters that are not valid. - -**/ -EFI_STATUS -EFIAPI -NvmExpressMediaPurge ( - IN MEDIA_SANITIZE_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT32 PurgeAction, - IN UINT32 OverwritePattern - ); - -/** - Format Media utilizes native format operations to modify sector/LBA size. - Secure erase actions are used to define how latent user data is erased. - - NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK. - - @param[in] This Indicates a pointer to the calling context. - @param[in] MediaId The media ID that the clear request is for. - @param[in] LbaSize Size of LBA (in terms of power of two: 2^n). - @param[in] SecureEraseAction Secure erase action, if any, to apply to format. - - 000b: No secure erase operation requested - - 001b: User Data Erase - - 010b: Cryptographic Erase - - 011b to 111b: Reserved - - @retval EFI_SUCCESS The media format request completed successfully on the device. - @retval EFI_WRITE_PROTECTED The device can't be formatted due to write protection. - @retval EFI_DEVICE_ERROR The device reported an error while attempting to perform the format operation. - @retval EFI_INVALID_PARAMETER The format request contains parameters that are not valid. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - - **/ -EFI_STATUS -EFIAPI -NvmExpressMediaFormat ( - IN MEDIA_SANITIZE_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT32 LbaSize, - IN UINT32 SecureEraseAction - ); - -#endif diff --git a/MsvmPkg/NvmExpressDxe/NvmExpressPassthru.c b/MsvmPkg/NvmExpressDxe/NvmExpressPassthru.c deleted file mode 100644 index 207de8dc91..0000000000 --- a/MsvmPkg/NvmExpressDxe/NvmExpressPassthru.c +++ /dev/null @@ -1,1470 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "NvmExpress.h" - -/** - Dump the execution status from a given completion queue entry. - - @param[in] Cq A pointer to the NVME_CQ item. - -**/ -VOID -NvmeDumpStatus ( - IN NVME_CQ *Cq - ) -{ - DEBUG ((DEBUG_VERBOSE, "Dump NVMe Completion Entry Status from [0x%x]:\n", Cq)); - - DEBUG ((DEBUG_VERBOSE, " SQ Identifier : [0x%x], Phase Tag : [%d], Cmd Identifier : [0x%x]\n", Cq->Sqid, Cq->Pt, Cq->Cid)); - - DEBUG ((DEBUG_VERBOSE, " NVMe Cmd Execution Result - ")); - - switch (Cq->Sct) { - case 0x0: - switch (Cq->Sc) { - case 0x0: - DEBUG ((DEBUG_VERBOSE, "Successful Completion\n")); - break; - case 0x1: - DEBUG ((DEBUG_VERBOSE, "Invalid Command Opcode\n")); - break; - case 0x2: - DEBUG ((DEBUG_VERBOSE, "Invalid Field in Command\n")); - break; - case 0x3: - DEBUG ((DEBUG_VERBOSE, "Command ID Conflict\n")); - break; - case 0x4: - DEBUG ((DEBUG_VERBOSE, "Data Transfer Error\n")); - break; - case 0x5: - DEBUG ((DEBUG_VERBOSE, "Commands Aborted due to Power Loss Notification\n")); - break; - case 0x6: - DEBUG ((DEBUG_VERBOSE, "Internal Device Error\n")); - break; - case 0x7: - DEBUG ((DEBUG_VERBOSE, "Command Abort Requested\n")); - break; - case 0x8: - DEBUG ((DEBUG_VERBOSE, "Command Aborted due to SQ Deletion\n")); - break; - case 0x9: - DEBUG ((DEBUG_VERBOSE, "Command Aborted due to Failed Fused Command\n")); - break; - case 0xA: - DEBUG ((DEBUG_VERBOSE, "Command Aborted due to Missing Fused Command\n")); - break; - case 0xB: - DEBUG ((DEBUG_VERBOSE, "Invalid Namespace or Format\n")); - break; - case 0xC: - DEBUG ((DEBUG_VERBOSE, "Command Sequence Error\n")); - break; - case 0xD: - DEBUG ((DEBUG_VERBOSE, "Invalid SGL Last Segment Descriptor\n")); - break; - case 0xE: - DEBUG ((DEBUG_VERBOSE, "Invalid Number of SGL Descriptors\n")); - break; - case 0xF: - DEBUG ((DEBUG_VERBOSE, "Data SGL Length Invalid\n")); - break; - case 0x10: - DEBUG ((DEBUG_VERBOSE, "Metadata SGL Length Invalid\n")); - break; - case 0x11: - DEBUG ((DEBUG_VERBOSE, "SGL Descriptor Type Invalid\n")); - break; - case 0x80: - DEBUG ((DEBUG_VERBOSE, "LBA Out of Range\n")); - break; - case 0x81: - DEBUG ((DEBUG_VERBOSE, "Capacity Exceeded\n")); - break; - case 0x82: - DEBUG ((DEBUG_VERBOSE, "Namespace Not Ready\n")); - break; - case 0x83: - DEBUG ((DEBUG_VERBOSE, "Reservation Conflict\n")); - break; - } - - break; - - case 0x1: - switch (Cq->Sc) { - case 0x0: - DEBUG ((DEBUG_VERBOSE, "Completion Queue Invalid\n")); - break; - case 0x1: - DEBUG ((DEBUG_VERBOSE, "Invalid Queue Identifier\n")); - break; - case 0x2: - DEBUG ((DEBUG_VERBOSE, "Maximum Queue Size Exceeded\n")); - break; - case 0x3: - DEBUG ((DEBUG_VERBOSE, "Abort Command Limit Exceeded\n")); - break; - case 0x5: - DEBUG ((DEBUG_VERBOSE, "Asynchronous Event Request Limit Exceeded\n")); - break; - case 0x6: - DEBUG ((DEBUG_VERBOSE, "Invalid Firmware Slot\n")); - break; - case 0x7: - DEBUG ((DEBUG_VERBOSE, "Invalid Firmware Image\n")); - break; - case 0x8: - DEBUG ((DEBUG_VERBOSE, "Invalid Interrupt Vector\n")); - break; - case 0x9: - DEBUG ((DEBUG_VERBOSE, "Invalid Log Page\n")); - break; - case 0xA: - DEBUG ((DEBUG_VERBOSE, "Invalid Format\n")); - break; - case 0xB: - DEBUG ((DEBUG_VERBOSE, "Firmware Application Requires Conventional Reset\n")); - break; - case 0xC: - DEBUG ((DEBUG_VERBOSE, "Invalid Queue Deletion\n")); - break; - case 0xD: - DEBUG ((DEBUG_VERBOSE, "Feature Identifier Not Saveable\n")); - break; - case 0xE: - DEBUG ((DEBUG_VERBOSE, "Feature Not Changeable\n")); - break; - case 0xF: - DEBUG ((DEBUG_VERBOSE, "Feature Not Namespace Specific\n")); - break; - case 0x10: - DEBUG ((DEBUG_VERBOSE, "Firmware Application Requires NVM Subsystem Reset\n")); - break; - case 0x80: - DEBUG ((DEBUG_VERBOSE, "Conflicting Attributes\n")); - break; - case 0x81: - DEBUG ((DEBUG_VERBOSE, "Invalid Protection Information\n")); - break; - case 0x82: - DEBUG ((DEBUG_VERBOSE, "Attempted Write to Read Only Range\n")); - break; - } - - break; - - case 0x2: - switch (Cq->Sc) { - case 0x80: - DEBUG ((DEBUG_VERBOSE, "Write Fault\n")); - break; - case 0x81: - DEBUG ((DEBUG_VERBOSE, "Unrecovered Read Error\n")); - break; - case 0x82: - DEBUG ((DEBUG_VERBOSE, "End-to-end Guard Check Error\n")); - break; - case 0x83: - DEBUG ((DEBUG_VERBOSE, "End-to-end Application Tag Check Error\n")); - break; - case 0x84: - DEBUG ((DEBUG_VERBOSE, "End-to-end Reference Tag Check Error\n")); - break; - case 0x85: - DEBUG ((DEBUG_VERBOSE, "Compare Failure\n")); - break; - case 0x86: - DEBUG ((DEBUG_VERBOSE, "Access Denied\n")); - break; - } - - break; - - default: - break; - } -} - -/** - Create PRP lists for data transfer which is larger than 2 memory pages. - Note here we calcuate the number of required PRP lists and allocate them at one time. - - @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param[in] PhysicalAddr The physical base address of data buffer. - @param[in] Pages The number of pages to be transfered. - @param[in] BouncePageListHead A pointer to PNVME_BOUNCE_PAGE list. - @param[out] PrpListHost The host base address of PRP lists. - @param[in,out] PrpListNo The number of PRP List. - @param[out] Mapping The mapping value returned from PciIo.Map(). - @param[out] ProtectionHandle Object used to track memory range. - - @retval The pointer to the first PRP List of the PRP lists. - -**/ -VOID * -NvmeCreatePrpList ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN EFI_PHYSICAL_ADDRESS PhysicalAddr, - IN UINTN Pages, - IN PNVME_BOUNCE_PAGE BouncePageListHead, // MS_HYP_CHANGE - OUT VOID **PrpListHost, - IN OUT UINTN *PrpListNo, - OUT VOID **Mapping, - IN OUT NVME_HOST_VISIBILITY_CONTEXT *HostVisibilityContext // MS_HYP_CHANGE - ) -{ - UINT64 PrpEntryNo; // MU_CHANGE - CodeQl Change - comparison mismatch - UINT64 PrpListBase; - UINT64 PrpListIndex; // MU_CHANGE - CodeQl Change - comparison mismatch - UINT64 PrpEntryIndex; // MU_CHANGE - CodeQl Change - comparison mismatch - UINT64 Remainder; - EFI_PHYSICAL_ADDRESS PrpListPhyAddr; - UINTN Bytes; - EFI_STATUS Status; - // MS_HYP_CHANGE BEGIN - PNVME_BOUNCE_PAGE BouncePage; - - ASSERT ((NvmExpressIsBounceActive() && (BouncePageListHead != NULL)) || - (!NvmExpressIsBounceActive() && (BouncePageListHead == NULL))); - // MS_HYP_CHANGE END - - // - // The number of Prp Entry in a memory page. - // - PrpEntryNo = EFI_PAGE_SIZE / sizeof (UINT64); - - // - // Calculate total PrpList number. - // - *PrpListNo = (UINTN)DivU64x64Remainder ((UINT64)Pages, (UINT64)PrpEntryNo - 1, &Remainder); - if (*PrpListNo == 0) { - *PrpListNo = 1; - } else if ((Remainder != 0) && (Remainder != 1)) { - *PrpListNo += 1; - } else if (Remainder == 1) { - Remainder = PrpEntryNo; - } else if (Remainder == 0) { - Remainder = PrpEntryNo - 1; - } - - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - *PrpListNo, - PrpListHost, - 0 - ); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: allocate PrpList failed %r\n", __func__, Status)); - return NULL; - } - - // MS_HYP_CHANGE BEGIN - if (IsIsolated()) - { - Status = NvmExpressMakeAddressRangeShared(HostVisibilityContext, - *PrpListHost, - (UINT32)*PrpListNo * EFI_PAGE_SIZE); - - if (EFI_ERROR(Status)) - { - DEBUG ((DEBUG_ERROR, "%a: share PrpList failed %r\n", __func__, Status)); - PciIo->FreeBuffer (PciIo, *PrpListNo, *PrpListHost); - *PrpListHost = NULL; - goto EXIT; - } - } - // MS_HYP_CHANGE END - - Bytes = EFI_PAGES_TO_SIZE (*PrpListNo); - Status = PciIo->Map ( - PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - *PrpListHost, - &Bytes, - &PrpListPhyAddr, - Mapping - ); - - if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (*PrpListNo))) { - DEBUG ((DEBUG_ERROR, "%a: map PrpList failed %r\n", __func__, Status)); - goto EXIT; - } - - // MS_HYP_CHANGE BEGIN - if (IsIsolated()) { - // - // Canonicalize the VA. - // - *PrpListHost = NvmExpressGetSharedVa(*PrpListHost); - } - // MS_HYP_CHANGE END - - // - // Fill all PRP lists except of last one. - // - - BouncePage = BouncePageListHead; // MS_HYP_CHANGE - - ZeroMem (*PrpListHost, Bytes); - for (PrpListIndex = 0; PrpListIndex < *PrpListNo - 1; ++PrpListIndex) { - PrpListBase = *(UINT64 *)PrpListHost + PrpListIndex * EFI_PAGE_SIZE; - - for (PrpEntryIndex = 0; PrpEntryIndex < PrpEntryNo; ++PrpEntryIndex) { - if (PrpEntryIndex != PrpEntryNo - 1) { - // - // Fill all PRP entries except of last one. - // - // MS_HYP_CHANGE BEGIN - if (BouncePageListHead != NULL) { - ASSERT (BouncePage != NULL); - *((UINT64 *)(UINTN)PrpListBase + PrpEntryIndex) = BouncePage->HostVisiblePA; - BouncePage = BouncePage->NextBouncePage; - - } else { - // MS_HYP_CHANGE END - *((UINT64 *)(UINTN)PrpListBase + PrpEntryIndex) = PhysicalAddr; - PhysicalAddr += EFI_PAGE_SIZE; - } // MS_HYP_CHANGE - } else { - // - // Fill last PRP entries with next PRP List pointer. - // - *((UINT64 *)(UINTN)PrpListBase + PrpEntryIndex) = PrpListPhyAddr + (PrpListIndex + 1) * EFI_PAGE_SIZE; - } - } - } - - // - // Fill last PRP list. - // - PrpListBase = *(UINT64 *)PrpListHost + PrpListIndex * EFI_PAGE_SIZE; - for (PrpEntryIndex = 0; PrpEntryIndex < Remainder; ++PrpEntryIndex) { - - // MS_HYP_CHANGE BEGIN - if (BouncePageListHead != NULL) { - ASSERT (BouncePage != NULL); - *((UINT64 *)(UINTN)PrpListBase + PrpEntryIndex) = BouncePage->HostVisiblePA; - BouncePage = BouncePage->NextBouncePage; - - } else { - // MS_HYP_CHANGE END - *((UINT64 *)(UINTN)PrpListBase + PrpEntryIndex) = PhysicalAddr; - PhysicalAddr += EFI_PAGE_SIZE; - } // MS_HYP_CHANGE - } - - return (VOID *)(UINTN)PrpListPhyAddr; - -EXIT: - return NULL; -} - -/** - Aborts the asynchronous PassThru requests. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA - data structure. - - @retval EFI_SUCCESS The asynchronous PassThru requests have been aborted. - @return EFI_DEVICE_ERROR Fail to abort all the asynchronous PassThru requests. - -**/ -EFI_STATUS -AbortAsyncPassThruTasks ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - LIST_ENTRY *Link; - LIST_ENTRY *NextLink; - NVME_BLKIO2_SUBTASK *Subtask; - NVME_BLKIO2_REQUEST *BlkIo2Request; - NVME_PASS_THRU_ASYNC_REQ *AsyncRequest; - EFI_BLOCK_IO2_TOKEN *Token; - EFI_TPL OldTpl; - EFI_STATUS Status; - - PciIo = Private->PciIo; - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - - // - // Cancel the unsubmitted subtasks. - // - for (Link = GetFirstNode (&Private->UnsubmittedSubtasks); - !IsNull (&Private->UnsubmittedSubtasks, Link); - Link = NextLink) - { - NextLink = GetNextNode (&Private->UnsubmittedSubtasks, Link); - Subtask = NVME_BLKIO2_SUBTASK_FROM_LINK (Link); - BlkIo2Request = Subtask->BlockIo2Request; - Token = BlkIo2Request->Token; - - BlkIo2Request->UnsubmittedSubtaskNum--; - if (Subtask->IsLast) { - BlkIo2Request->LastSubtaskSubmitted = TRUE; - } - - Token->TransactionStatus = EFI_ABORTED; - - RemoveEntryList (Link); - InsertTailList (&BlkIo2Request->SubtasksQueue, Link); - gBS->SignalEvent (Subtask->Event); - } - - // - // Cleanup the resources for the asynchronous PassThru requests. - // - for (Link = GetFirstNode (&Private->AsyncPassThruQueue); - !IsNull (&Private->AsyncPassThruQueue, Link); - Link = NextLink) - { - NextLink = GetNextNode (&Private->AsyncPassThruQueue, Link); - AsyncRequest = NVME_PASS_THRU_ASYNC_REQ_FROM_THIS (Link); - - // MS_HYP_CHANGE BEGIN - if (AsyncRequest->TransferBouncePageList != NULL) { - NvmExpressReleaseBouncePages (Private, - AsyncRequest->TransferBouncePageList); - } - - if (AsyncRequest->MetadataBouncePageList != NULL) { - NvmExpressReleaseBouncePages (Private, - AsyncRequest->MetadataBouncePageList); - } - // MS_HYP_CHANGE END - - if (AsyncRequest->MapData != NULL) { - PciIo->Unmap (PciIo, AsyncRequest->MapData); - } - - if (AsyncRequest->MapMeta != NULL) { - PciIo->Unmap (PciIo, AsyncRequest->MapMeta); - } - - if (AsyncRequest->MapPrpList != NULL) { - PciIo->Unmap (PciIo, AsyncRequest->MapPrpList); - } - - if (AsyncRequest->PrpListHost != NULL) { - - // MS_HYP_CHANGE BEGIN - if (IsIsolated()) { - NvmExpressMakeAddressRangePrivate(&AsyncRequest->PrpListHostVisibilityContext, AsyncRequest->PrpListHost); - } - // MS_HYP_CHANGE END - - PciIo->FreeBuffer ( - PciIo, - AsyncRequest->PrpListNo, - AsyncRequest->PrpListHost - ); - } - - RemoveEntryList (Link); - gBS->SignalEvent (AsyncRequest->CallerEvent); - FreePool (AsyncRequest); - } - - if (IsListEmpty (&Private->AsyncPassThruQueue) && - IsListEmpty (&Private->UnsubmittedSubtasks)) - { - Status = EFI_SUCCESS; - } else { - Status = EFI_DEVICE_ERROR; - } - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Sends an NVM Express Command Packet to an NVM Express controller or namespace. This function supports - both blocking I/O and non-blocking I/O. The blocking I/O functionality is required, and the non-blocking - I/O functionality is optional. - - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] NamespaceId A 32 bit namespace ID as defined in the NVMe specification to which the NVM Express Command - Packet will be sent. A value of 0 denotes the NVM Express controller, a value of all 0xFF's - (all bytes are 0xFF) in the namespace ID specifies that the command packet should be sent to - all valid namespaces. - @param[in,out] Packet A pointer to the NVM Express Command Packet. - @param[in] Event If non-blocking I/O is not supported then Event is ignored, and blocking I/O is performed. - If Event is NULL, then blocking I/O is performed. If Event is not NULL and non-blocking I/O - is supported, then non-blocking I/O is performed, and Event will be signaled when the NVM - Express Command Packet completes. - - @retval EFI_SUCCESS The NVM Express Command Packet was sent by the host. TransferLength bytes were transferred - to, or from DataBuffer. - @retval EFI_BAD_BUFFER_SIZE The NVM Express Command Packet was not executed. The number of bytes that could be transferred - is returned in TransferLength. - @retval EFI_NOT_READY The NVM Express Command Packet could not be sent because the controller is not ready. The caller - may retry again later. - @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the NVM Express Command Packet. - @retval EFI_INVALID_PARAMETER NamespaceId or the contents of EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET are invalid. The NVM - Express Command Packet was not sent, so no additional status information is available. - @retval EFI_UNSUPPORTED The command described by the NVM Express Command Packet is not supported by the NVM Express - controller. The NVM Express Command Packet was not sent so no additional status information - is available. - @retval EFI_TIMEOUT A timeout occurred while waiting for the NVM Express Command Packet to execute. - -**/ -EFI_STATUS -EFIAPI -NvmExpressPassThru ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN UINT32 NamespaceId, - IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet, - IN EFI_EVENT Event OPTIONAL - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_STATUS Status; - EFI_STATUS PreviousStatus; - EFI_PCI_IO_PROTOCOL *PciIo; - NVME_SQ *Sq; - volatile NVME_CQ *Cq; - UINT16 QueueId; - UINT16 QueueSize; - UINT32 Bytes; - UINT16 Offset; - EFI_EVENT TimerEvent; - EFI_PCI_IO_PROTOCOL_OPERATION Flag; - EFI_PHYSICAL_ADDRESS PhyAddr; - VOID *MapData; - VOID *MapMeta; - VOID *MapPrpList; - UINTN MapLength; - UINT64 *Prp; - VOID *PrpListHost; - UINTN PrpListNo; - UINT32 Attributes; - UINT32 IoAlign; - UINT32 MaxTransLen; - UINT32 Data; - NVME_PASS_THRU_ASYNC_REQ *AsyncRequest; - EFI_TPL OldTpl; - // MS_HYP_CHANGE BEGIN - UINT32 BouncePageCount; - NVME_HOST_VISIBILITY_CONTEXT PrpListVisibilityContext; - PNVME_BOUNCE_PAGE TransferBouncePageList; - PNVME_BOUNCE_PAGE MetadataBouncePageList; - // MS_HYP_CHANGE END - - // - // check the data fields in Packet parameter. - // - if ((This == NULL) || (Packet == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((Packet->NvmeCmd == NULL) || (Packet->NvmeCompletion == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((Packet->QueueType != NVME_ADMIN_QUEUE) && (Packet->QueueType != NVME_IO_QUEUE)) { - return EFI_INVALID_PARAMETER; - } - - // - // 'Attributes' with neither EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL nor - // EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL set is an illegal - // configuration. - // - Attributes = This->Mode->Attributes; - if ((Attributes & (EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL | - EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL)) == 0) - { - return EFI_INVALID_PARAMETER; - } - - // - // Buffer alignment check for TransferBuffer & MetadataBuffer. - // - IoAlign = This->Mode->IoAlign; - if ((IoAlign > 0) && (((UINTN)Packet->TransferBuffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - if ((IoAlign > 0) && (((UINTN)Packet->MetadataBuffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This); - - // - // Check NamespaceId is valid or not. - // - if ((NamespaceId > Private->ControllerData->Nn) && - (NamespaceId != (UINT32)-1)) - { - return EFI_INVALID_PARAMETER; - } - - // - // Check whether TransferLength exceeds the maximum data transfer size. - // - if (Private->ControllerData->Mdts != 0) { - MaxTransLen = (1 << (Private->ControllerData->Mdts)) * - (1 << (Private->Cap.Mpsmin + 12)); - if (Packet->TransferLength > MaxTransLen) { - Packet->TransferLength = MaxTransLen; - return EFI_BAD_BUFFER_SIZE; - } - } - - PciIo = Private->PciIo; - MapData = NULL; - MapMeta = NULL; - MapPrpList = NULL; - PrpListHost = NULL; - PrpListNo = 0; - Prp = NULL; - TimerEvent = NULL; - Status = EFI_SUCCESS; - // MS_HYP_CHANGE BEGIN - TransferBouncePageList = NULL; - MetadataBouncePageList = NULL; - // MS_HYP_CHANGE END - - // MU_CHANGE [BEGIN] - Support alternative hardware queue sizes in NVME driver - if (PcdGetBool (PcdSupportAlternativeQueueSize)) { - QueueSize = MIN (NVME_ALTERNATIVE_MAX_QUEUE_SIZE, Private->Cap.Mqes) + 1; - } else { - QueueSize = MIN (NVME_ASYNC_CSQ_SIZE, Private->Cap.Mqes) + 1; - } - - // MU_CHANGE [END] - Support alternative hardware queue sizes in NVME driver - - if (Packet->QueueType == NVME_ADMIN_QUEUE) { - QueueId = 0; - } else { - if (Event == NULL) { - QueueId = 1; - } else { - QueueId = 2; - - // - // Submission queue full check. - // - if ((Private->SqTdbl[QueueId].Sqt + 1) % QueueSize == - Private->AsyncSqHead) - { - return EFI_NOT_READY; - } - } - } - - Sq = Private->SqBuffer[QueueId] + Private->SqTdbl[QueueId].Sqt; - Cq = Private->CqBuffer[QueueId] + Private->CqHdbl[QueueId].Cqh; - - if (Packet->NvmeCmd->Nsid != NamespaceId) { - return EFI_INVALID_PARAMETER; - } - - // MU_CHANGE - Support alternative hardware queue sizes in NVME driver - // - // Nvme DXE driver polls phase bit for CQe completion. - // Explicitly assign phase bit with the bit before completion. - // A flipped phase bit will be assigned by device upon CQe completes. - // - Cq->Pt = Private->Pt[QueueId]; - - ZeroMem (Sq, sizeof (NVME_SQ)); - Sq->Opc = (UINT8)Packet->NvmeCmd->Cdw0.Opcode; - Sq->Fuse = (UINT8)Packet->NvmeCmd->Cdw0.FusedOperation; - Sq->Cid = Private->Cid[QueueId]++; - Sq->Nsid = Packet->NvmeCmd->Nsid; - - // - // Currently we only support PRP for data transfer, SGL is NOT supported. - // - ASSERT (Sq->Psdt == 0); - if (Sq->Psdt != 0) { - DEBUG ((DEBUG_ERROR, "NvmExpressPassThru: doesn't support SGL mechanism\n")); - return EFI_UNSUPPORTED; - } - - Sq->Prp[0] = (UINT64)(UINTN)Packet->TransferBuffer; - if ((Packet->QueueType == NVME_ADMIN_QUEUE) && - ((Sq->Opc == NVME_ADMIN_CRIOCQ_CMD) || (Sq->Opc == NVME_ADMIN_CRIOSQ_CMD))) - { - // - // Currently, we only use the IO Completion/Submission queues created internally - // by this driver during controller initialization. Any other IO queues created - // will not be consumed here. The value is little to accept external IO queue - // creation requests, so here we will return EFI_UNSUPPORTED for external IO - // queue creation request. - // - if (!Private->CreateIoQueue) { - DEBUG ((DEBUG_ERROR, "NvmExpressPassThru: Does not support external IO queues creation request.\n")); - return EFI_UNSUPPORTED; - } - } else if ((Sq->Opc & (BIT0 | BIT1)) != 0) { - // - // If the NVMe cmd has data in or out, then mapping the user buffer to the PCI controller specific addresses. - // - if (((Packet->TransferLength != 0) && (Packet->TransferBuffer == NULL)) || - ((Packet->TransferLength == 0) && (Packet->TransferBuffer != NULL))) - { - return EFI_INVALID_PARAMETER; - } - - if ((Sq->Opc & BIT0) != 0) { - Flag = EfiPciIoOperationBusMasterRead; - } else { - Flag = EfiPciIoOperationBusMasterWrite; - } - - if ((Packet->TransferLength != 0) && (Packet->TransferBuffer != NULL)) { - - // MS_HYP_CHANGE BEGIN - if (NvmExpressIsBounceActive()) { - - // - // Use bounce buffer for isolated VMs. - // - Offset = (UINT16)((UINT64)Packet->TransferBuffer & (EFI_PAGE_SIZE - 1)); - BouncePageCount = EFI_SIZE_TO_PAGES(Packet->TransferLength + Offset); - TransferBouncePageList = NvmExpressAcquireBouncePages (Private, - BouncePageCount); - if (TransferBouncePageList == NULL) { - DEBUG ((DEBUG_ERROR, "%a: Transfer bounce buffer allocation error - %r!\n", __func__, Status)); - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } - - if ((Sq->Opc & BIT0) != 0) { - - // - // Data transfer direction from host to controller. Copy into bounce buffer. - // - NvmExpressCopyBouncePagesToExternalBuffer (Packet->TransferBuffer, - Packet->TransferLength, - TransferBouncePageList, - TRUE); - } else { - NvmExpressZeroBouncePageList (TransferBouncePageList); - } - PhyAddr = TransferBouncePageList->HostVisiblePA + Offset; - } else { - // MS_HYP_CHANGE END - MapLength = Packet->TransferLength; - Status = PciIo->Map ( - PciIo, - Flag, - Packet->TransferBuffer, - &MapLength, - &PhyAddr, - &MapData - ); - if (EFI_ERROR (Status) || (Packet->TransferLength != MapLength)) { - DEBUG ((DEBUG_ERROR, "%a: Map transfer buffer error - %r!\n", __func__, Status)); - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } - - } // MS_HYP_CHANGE - - Sq->Prp[0] = PhyAddr; - - // MS_HYP_CHANGE this block is lifted from lower in the function to set Sq->Prp[1] correctly - // - // If the buffer size spans more than two memory pages (page size as defined in CC.Mps), - // then build a PRP list in the second PRP submission queue entry. - // - Offset = ((UINT16)Sq->Prp[0]) & (EFI_PAGE_SIZE - 1); - Bytes = Packet->TransferLength; - - if ((Offset + Bytes) > (EFI_PAGE_SIZE * 2)) { - // - // Create PrpList for remaining data buffer. - // - PhyAddr = (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1); - Prp = NvmeCreatePrpList (PciIo, - PhyAddr, - EFI_SIZE_TO_PAGES (Offset + Bytes) - 1, - // MS_HYP_CHANGE - ((TransferBouncePageList != NULL)? - TransferBouncePageList->NextBouncePage:NULL), - &PrpListHost, - &PrpListNo, - &MapPrpList, - &PrpListVisibilityContext); - if (Prp == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } - - Sq->Prp[1] = (UINT64)(UINTN)Prp; - } else if ((Offset + Bytes) > EFI_PAGE_SIZE) { - - // MS_HYP_CHANGE BEGIN - if (TransferBouncePageList != NULL) { - // - // Next page in bounce buffer list - // - PNVME_BOUNCE_PAGE bouncePage; - bouncePage = TransferBouncePageList->NextBouncePage; - ASSERT (bouncePage != NULL); - - Sq->Prp[1] = bouncePage->HostVisiblePA; - } else { - // MS_HYP_CHANGE END - Sq->Prp[1] = (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1); - } // MS_HYP_CHANGE - } - } - - if ((Packet->MetadataLength != 0) && (Packet->MetadataBuffer != NULL)) { - // MS_HYP_CHANGE BEGIN - if (NvmExpressIsBounceActive()) { - - // - // Use bounce buffer for isolated VMs. - // - Offset = (UINT16)((UINT64)Packet->MetadataBuffer & (EFI_PAGE_SIZE - 1)); - BouncePageCount = EFI_SIZE_TO_PAGES(Packet->MetadataLength + Offset); - - // - // Metadata buffer cannot span more than 1 page - // - ASSERT (BouncePageCount == 1); - MetadataBouncePageList = NvmExpressAcquireBouncePages (Private, - BouncePageCount); - if (MetadataBouncePageList == NULL) { - DEBUG ((DEBUG_ERROR, "%a: Metadata bounce buffer allocation error - %r!\n", __func__, Status)); - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } - if ((Sq->Opc & BIT0) != 0) { - - // - // Data transfer direction from host to controller. Copy - // into bounce buffer. - // - NvmExpressCopyBouncePagesToExternalBuffer (Packet->MetadataBuffer, - Packet->MetadataLength, - MetadataBouncePageList, - TRUE); - } else { - NvmExpressZeroBouncePageList (MetadataBouncePageList); - } - PhyAddr = MetadataBouncePageList->HostVisiblePA + Offset; - } else { - // MS_HYP_CHANGE END - MapLength = Packet->MetadataLength; - Status = PciIo->Map ( - PciIo, - Flag, - Packet->MetadataBuffer, - &MapLength, - &PhyAddr, - &MapMeta - ); - if (EFI_ERROR (Status) || (Packet->MetadataLength != MapLength)) { - DEBUG ((DEBUG_ERROR, "%a: Map packet metadata buffer error - %r!\n", __func__, Status)); - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } - } // MS_HYP_CHANGE - Sq->Mptr = PhyAddr; - } - } - - if (Packet->NvmeCmd->Flags & CDW2_VALID) { - Sq->Rsvd2 = (UINT64)Packet->NvmeCmd->Cdw2; - } - - if (Packet->NvmeCmd->Flags & CDW3_VALID) { - Sq->Rsvd2 |= LShiftU64 ((UINT64)Packet->NvmeCmd->Cdw3, 32); - } - - if (Packet->NvmeCmd->Flags & CDW10_VALID) { - Sq->Payload.Raw.Cdw10 = Packet->NvmeCmd->Cdw10; - } - - if (Packet->NvmeCmd->Flags & CDW11_VALID) { - Sq->Payload.Raw.Cdw11 = Packet->NvmeCmd->Cdw11; - } - - if (Packet->NvmeCmd->Flags & CDW12_VALID) { - Sq->Payload.Raw.Cdw12 = Packet->NvmeCmd->Cdw12; - } - - if (Packet->NvmeCmd->Flags & CDW13_VALID) { - Sq->Payload.Raw.Cdw13 = Packet->NvmeCmd->Cdw13; - } - - if (Packet->NvmeCmd->Flags & CDW14_VALID) { - Sq->Payload.Raw.Cdw14 = Packet->NvmeCmd->Cdw14; - } - - if (Packet->NvmeCmd->Flags & CDW15_VALID) { - Sq->Payload.Raw.Cdw15 = Packet->NvmeCmd->Cdw15; - } - - // MU_CHANGE [BEGIN] - Support alternative hardware queue sizes in NVME driver - if (PcdGetBool (PcdSupportAlternativeQueueSize)) { - Private->SqTdbl[QueueId].Sqt = (Private->SqTdbl[QueueId].Sqt + 1) % QueueSize; - } else { - // - // Ring the submission queue doorbell. - // - if ((Event != NULL) && (QueueId != 0)) { - Private->SqTdbl[QueueId].Sqt = - (Private->SqTdbl[QueueId].Sqt + 1) % QueueSize; - } else { - Private->SqTdbl[QueueId].Sqt ^= 1; - } - } - - // MU_CHANGE [END] - Support alternative hardware queue sizes in NVME driver - - Data = ReadUnaligned32 ((UINT32 *)&Private->SqTdbl[QueueId]); - Status = PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_SQTDBL_OFFSET (QueueId, Private->Cap.Dstrd), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - goto EXIT; - } - - // - // For non-blocking requests, return directly if the command is placed - // in the submission queue. - // - if ((Event != NULL) && (QueueId != 0)) { - AsyncRequest = AllocateZeroPool (sizeof (NVME_PASS_THRU_ASYNC_REQ)); - if (AsyncRequest == NULL) { - Status = EFI_DEVICE_ERROR; - goto EXIT; - } - - AsyncRequest->Signature = NVME_PASS_THRU_ASYNC_REQ_SIG; - AsyncRequest->Packet = Packet; - AsyncRequest->CommandId = Sq->Cid; - AsyncRequest->CallerEvent = Event; - AsyncRequest->MapData = MapData; - AsyncRequest->MapMeta = MapMeta; - AsyncRequest->MapPrpList = MapPrpList; - AsyncRequest->PrpListNo = PrpListNo; - AsyncRequest->PrpListHost = PrpListHost; - // MS_HYP_CHANGE BEGIN - AsyncRequest->PrpListHostVisibilityContext.RangeProtectionHandle = PrpListVisibilityContext.RangeProtectionHandle; - AsyncRequest->TransferBouncePageList = TransferBouncePageList; - AsyncRequest->MetadataBouncePageList = MetadataBouncePageList; - // MS_HYP_CHANGE END - - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - InsertTailList (&Private->AsyncPassThruQueue, &AsyncRequest->Link); - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; - } - - Status = gBS->CreateEvent ( - EVT_TIMER, - TPL_CALLBACK, - NULL, - NULL, - &TimerEvent - ); - if (EFI_ERROR (Status)) { - goto EXIT; - } - - Status = gBS->SetTimer (TimerEvent, TimerRelative, Packet->CommandTimeout); - - if (EFI_ERROR (Status)) { - goto EXIT; - } - - // - // Wait for completion queue to get filled in. - // - Status = EFI_TIMEOUT; - while (EFI_ERROR (gBS->CheckEvent (TimerEvent))) { - if (Cq->Pt != Private->Pt[QueueId]) { - Status = EFI_SUCCESS; - break; - } - } - - // - // Check the NVMe cmd execution result - // - if (Status != EFI_TIMEOUT) { - if ((Cq->Sct == 0) && (Cq->Sc == 0)) { - Status = EFI_SUCCESS; - - // MS_HYP_CHANGE BEGIN - // - // Copy back data from the bounce buffers - // - if (Packet->NvmeCmd->Cdw0.Opcode & BIT1) { - if (TransferBouncePageList != NULL) { - NvmExpressCopyBouncePagesToExternalBuffer(Packet->TransferBuffer, - Packet->TransferLength, - TransferBouncePageList, - FALSE); - } - - if (MetadataBouncePageList != NULL) { - NvmExpressCopyBouncePagesToExternalBuffer(Packet->MetadataBuffer, - Packet->MetadataLength, - MetadataBouncePageList, - FALSE); - } - } - // MS_HYP_CHANGE END - } else { - Status = EFI_DEVICE_ERROR; - // - // Dump every completion entry status for debugging. - // - DEBUG_CODE_BEGIN (); - NvmeDumpStatus ((NVME_CQ *)Cq); - DEBUG_CODE_END (); - } - - // - // Copy the Respose Queue entry for this command to the callers response buffer - // - CopyMem (Packet->NvmeCompletion, (VOID *)Cq, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - } else { - ReportStatusCode ((EFI_ERROR_MAJOR | EFI_ERROR_CODE), (EFI_IO_BUS_SCSI | EFI_IOB_EC_INTERFACE_ERROR)); - - // - // Timeout occurs for an NVMe command. Reset the controller to abort the - // outstanding commands. - // - DEBUG ((DEBUG_ERROR, "NvmExpressPassThru: Timeout occurs for an NVMe command.\n")); - - // - // Disable the timer to trigger the process of async transfers temporarily. - // - Status = gBS->SetTimer (Private->TimerEvent, TimerCancel, 0); - if (EFI_ERROR (Status)) { - goto EXIT; - } - - // - // Reset the NVMe controller. - // - Status = NvmeControllerReset (Private); // MU_CHANGE - Allocate IO Queue Buffer - if (!EFI_ERROR (Status)) { - Status = AbortAsyncPassThruTasks (Private); - if (!EFI_ERROR (Status)) { - // - // Re-enable the timer to trigger the process of async transfers. - // - Status = gBS->SetTimer (Private->TimerEvent, TimerPeriodic, NVME_HC_ASYNC_TIMER); - if (!EFI_ERROR (Status)) { - // - // Return EFI_TIMEOUT to indicate a timeout occurs for NVMe PassThru command. - // - Status = EFI_TIMEOUT; - } - } - } else { - Status = EFI_DEVICE_ERROR; - } - - goto EXIT; - } - - // MU_CHANGE [BEGIN] - Support alternative hardware queue sizes in NVME driver - if (PcdGetBool (PcdSupportAlternativeQueueSize)) { - Private->CqHdbl[QueueId].Cqh = (Private->CqHdbl[QueueId].Cqh + 1) % QueueSize; - if (Private->CqHdbl[QueueId].Cqh == 0) { - Private->Pt[QueueId] ^= 1; - } - } else { - if ((Private->CqHdbl[QueueId].Cqh ^= 1) == 0) { - Private->Pt[QueueId] ^= 1; - } - } - - // MU_CHANGE [END] - Support alternative hardware queue sizes in NVME driver - - Data = ReadUnaligned32 ((UINT32 *)&Private->CqHdbl[QueueId]); - PreviousStatus = Status; - Status = PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CQHDBL_OFFSET (QueueId, Private->Cap.Dstrd), - 1, - &Data - ); - // The return status of PciIo->Mem.Write should not override - // previous status if previous status contains error. - Status = EFI_ERROR (PreviousStatus) ? PreviousStatus : Status; - - // - // For now, the code does not support the non-blocking feature for admin queue. - // If Event is not NULL for admin queue, signal the caller's event here. - // - if (Event != NULL) { - ASSERT (QueueId == 0); - gBS->SignalEvent (Event); - } - -EXIT: - // MS_HYP_CHANGE BEGIN - if (TransferBouncePageList != NULL) { - NvmExpressReleaseBouncePages (Private, TransferBouncePageList); - } - - if (MetadataBouncePageList != NULL) { - NvmExpressReleaseBouncePages (Private, MetadataBouncePageList); - } - // MS_HYP_CHANGE END - - if (MapData != NULL) { - PciIo->Unmap ( - PciIo, - MapData - ); - } - - if (MapMeta != NULL) { - PciIo->Unmap ( - PciIo, - MapMeta - ); - } - - if (MapPrpList != NULL) { - PciIo->Unmap ( - PciIo, - MapPrpList - ); - } - - if (PrpListHost != NULL) { - // MS_HYP_CHANGE BEGIN - if (IsIsolated()) { - NvmExpressMakeAddressRangePrivate(&PrpListVisibilityContext, PrpListHost); - } - // MS_HYP_CHANGE END - PciIo->FreeBuffer (PciIo, PrpListNo, PrpListHost); - PrpListHost = NULL; - } - - if (TimerEvent != NULL) { - gBS->CloseEvent (TimerEvent); - } - - return Status; -} - -/** - Used to retrieve the next namespace ID for this NVM Express controller. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNextNamespace() function retrieves the next valid - namespace ID on this NVM Express controller. - - If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the first valid namespace - ID defined on the NVM Express controller is returned in the location pointed to by NamespaceId - and a status of EFI_SUCCESS is returned. - - If on input the value pointed to by NamespaceId is an invalid namespace ID other than 0xFFFFFFFF, - then EFI_INVALID_PARAMETER is returned. - - If on input the value pointed to by NamespaceId is a valid namespace ID, then the next valid - namespace ID on the NVM Express controller is returned in the location pointed to by NamespaceId, - and EFI_SUCCESS is returned. - - If the value pointed to by NamespaceId is the namespace ID of the last namespace on the NVM - Express controller, then EFI_NOT_FOUND is returned. - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in,out] NamespaceId On input, a pointer to a legal NamespaceId for an NVM Express - namespace present on the NVM Express controller. On output, a - pointer to the next NamespaceId of an NVM Express namespace on - an NVM Express controller. An input value of 0xFFFFFFFF retrieves - the first NamespaceId for an NVM Express namespace present on an - NVM Express controller. - - @retval EFI_SUCCESS The Namespace ID of the next Namespace was returned. - @retval EFI_NOT_FOUND There are no more namespaces defined on this controller. - @retval EFI_INVALID_PARAMETER NamespaceId is an invalid value other than 0xFFFFFFFF. - -**/ -EFI_STATUS -EFIAPI -NvmExpressGetNextNamespace ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN OUT UINT32 *NamespaceId - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - NVME_ADMIN_NAMESPACE_DATA *NamespaceData; - UINT32 NextNamespaceId; - EFI_STATUS Status; - - if ((This == NULL) || (NamespaceId == NULL)) { - return EFI_INVALID_PARAMETER; - } - - NamespaceData = NULL; - Status = EFI_NOT_FOUND; - - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This); - // - // If the NamespaceId input value is 0xFFFFFFFF, then get the first valid namespace ID - // - if (*NamespaceId == 0xFFFFFFFF) { - // - // Start with the first namespace ID - // - NextNamespaceId = 1; - // - // Allocate buffer for Identify Namespace data. - // - NamespaceData = (NVME_ADMIN_NAMESPACE_DATA *)AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA)); - - if (NamespaceData == NULL) { - return EFI_NOT_FOUND; - } - - Status = NvmeIdentifyNamespace (Private, NextNamespaceId, NamespaceData); - if (EFI_ERROR (Status)) { - goto Done; - } - - *NamespaceId = NextNamespaceId; - } else { - if (*NamespaceId > Private->ControllerData->Nn) { - return EFI_INVALID_PARAMETER; - } - - NextNamespaceId = *NamespaceId + 1; - if (NextNamespaceId > Private->ControllerData->Nn) { - return EFI_NOT_FOUND; - } - - // - // Allocate buffer for Identify Namespace data. - // - NamespaceData = (NVME_ADMIN_NAMESPACE_DATA *)AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA)); - if (NamespaceData == NULL) { - return EFI_NOT_FOUND; - } - - Status = NvmeIdentifyNamespace (Private, NextNamespaceId, NamespaceData); - if (EFI_ERROR (Status)) { - goto Done; - } - - *NamespaceId = NextNamespaceId; - } - -Done: - if (NamespaceData != NULL) { - FreePool (NamespaceData); - } - - return Status; -} - -/** - Used to translate a device path node to a namespace ID. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNamespace() function determines the namespace ID associated with the - namespace described by DevicePath. - - If DevicePath is a device path node type that the NVM Express Pass Thru driver supports, then the NVM Express - Pass Thru driver will attempt to translate the contents DevicePath into a namespace ID. - - If this translation is successful, then that namespace ID is returned in NamespaceId, and EFI_SUCCESS is returned - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] DevicePath A pointer to the device path node that describes an NVM Express namespace on - the NVM Express controller. - @param[out] NamespaceId The NVM Express namespace ID contained in the device path node. - - @retval EFI_SUCCESS DevicePath was successfully translated to NamespaceId. - @retval EFI_INVALID_PARAMETER If DevicePath or NamespaceId are NULL, then EFI_INVALID_PARAMETER is returned. - @retval EFI_UNSUPPORTED If DevicePath is not a device path node type that the NVM Express Pass Thru driver - supports, then EFI_UNSUPPORTED is returned. - @retval EFI_NOT_FOUND If DevicePath is a device path node type that the NVM Express Pass Thru driver - supports, but there is not a valid translation from DevicePath to a namespace ID, - then EFI_NOT_FOUND is returned. -**/ -EFI_STATUS -EFIAPI -NvmExpressGetNamespace ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT UINT32 *NamespaceId - ) -{ - NVME_NAMESPACE_DEVICE_PATH *Node; - NVME_CONTROLLER_PRIVATE_DATA *Private; - - if ((This == NULL) || (DevicePath == NULL) || (NamespaceId == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (DevicePath->Type != MESSAGING_DEVICE_PATH) { - return EFI_UNSUPPORTED; - } - - Node = (NVME_NAMESPACE_DEVICE_PATH *)DevicePath; - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This); - - if (DevicePath->SubType == MSG_NVME_NAMESPACE_DP) { - if (DevicePathNodeLength (DevicePath) != sizeof (NVME_NAMESPACE_DEVICE_PATH)) { - return EFI_NOT_FOUND; - } - - // - // Check NamespaceId in the device path node is valid or not. - // - if ((Node->NamespaceId == 0) || - (Node->NamespaceId > Private->ControllerData->Nn)) - { - return EFI_NOT_FOUND; - } - - *NamespaceId = Node->NamespaceId; - - return EFI_SUCCESS; - } else { - return EFI_UNSUPPORTED; - } -} - -/** - Used to allocate and build a device path node for an NVM Express namespace on an NVM Express controller. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.BuildDevicePath() function allocates and builds a single device - path node for the NVM Express namespace specified by NamespaceId. - - If the NamespaceId is not valid, then EFI_NOT_FOUND is returned. - - If DevicePath is NULL, then EFI_INVALID_PARAMETER is returned. - - If there are not enough resources to allocate the device path node, then EFI_OUT_OF_RESOURCES is returned. - - Otherwise, DevicePath is allocated with the boot service AllocatePool(), the contents of DevicePath are - initialized to describe the NVM Express namespace specified by NamespaceId, and EFI_SUCCESS is returned. - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be - allocated and built. Caller must set the NamespaceId to zero if the - device path node will contain a valid UUID. - @param[in,out] DevicePath A pointer to a single device path node that describes the NVM Express - namespace specified by NamespaceId. This function is responsible for - allocating the buffer DevicePath with the boot service AllocatePool(). - It is the caller's responsibility to free DevicePath when the caller - is finished with DevicePath. - @retval EFI_SUCCESS The device path node that describes the NVM Express namespace specified - by NamespaceId was allocated and returned in DevicePath. - @retval EFI_NOT_FOUND The NamespaceId is not valid. - @retval EFI_INVALID_PARAMETER DevicePath is NULL. - @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the DevicePath node. - -**/ -EFI_STATUS -EFIAPI -NvmExpressBuildDevicePath ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN UINT32 NamespaceId, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath - ) -{ - NVME_NAMESPACE_DEVICE_PATH *Node; - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_STATUS Status; - NVME_ADMIN_NAMESPACE_DATA *NamespaceData; - - // - // Validate parameters - // - if ((This == NULL) || (DevicePath == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Status = EFI_SUCCESS; - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This); - - // - // Check NamespaceId is valid or not. - // - if ((NamespaceId == 0) || - (NamespaceId > Private->ControllerData->Nn)) - { - return EFI_NOT_FOUND; - } - - Node = (NVME_NAMESPACE_DEVICE_PATH *)AllocateZeroPool (sizeof (NVME_NAMESPACE_DEVICE_PATH)); - if (Node == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Node->Header.Type = MESSAGING_DEVICE_PATH; - Node->Header.SubType = MSG_NVME_NAMESPACE_DP; - SetDevicePathNodeLength (&Node->Header, sizeof (NVME_NAMESPACE_DEVICE_PATH)); - Node->NamespaceId = NamespaceId; - - // - // Allocate a buffer for Identify Namespace data. - // - NamespaceData = NULL; - NamespaceData = AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA)); - if (NamespaceData == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - - // - // Get UUID from specified Identify Namespace data. - // - Status = NvmeIdentifyNamespace ( - Private, - NamespaceId, - (VOID *)NamespaceData - ); - - if (EFI_ERROR (Status)) { - goto Exit; - } - - Node->NamespaceUuid = NamespaceData->Eui64; - - *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Node; - -Exit: - if (NamespaceData != NULL) { - FreePool (NamespaceData); - } - - if (EFI_ERROR (Status)) { - FreePool (Node); - } - - return Status; -} diff --git a/MsvmPkg/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c b/MsvmPkg/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c deleted file mode 100644 index 9227ef8abe..0000000000 --- a/MsvmPkg/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c +++ /dev/null @@ -1,983 +0,0 @@ -/** @file -- MediaSanitizeUnitTest.c - Placeholder/framework for developing a Media Sanitize unit test package. - - Copyright (c) Microsoft Corporation. - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../NvmExpress.h" -#include "../NvmExpressBlockIo.h" -#include "../NvmExpressMediaSanitize.h" -#include "../NvmExpressHci.h" - -EFI_STATUS -EFIAPI -NvmeDeviceUnitTestPassthru ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN UINT32 NamespaceId, - IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet, - IN EFI_EVENT Event OPTIONAL - ) -{ - // - // Parse command packet for unit testing - // - EFI_NVM_EXPRESS_COMMAND *Command; - EFI_NVM_EXPRESS_COMPLETION *Completion; - NVME_CQ *Cqe; - NVME_ADMIN_FORMAT_NVM FormatNvmCdw10; - NVME_ADMIN_SANITIZE SanitizeCdw1011; - - ASSERT (This); - ASSERT (Packet); - - Command = Packet->NvmeCmd; - Completion = Packet->NvmeCompletion; - Cqe = (NVME_CQ *)Completion; - - ZeroMem (&FormatNvmCdw10, sizeof (NVME_ADMIN_FORMAT_NVM)); - ZeroMem (&SanitizeCdw1011, sizeof (NVME_ADMIN_SANITIZE)); - - switch (Command->Cdw0.Opcode) { - case NVME_ADMIN_FORMAT_NVM_CMD: - UT_LOG_VERBOSE ("%a: Opcode = NVME_ADMIN_FORMAT_NVM_CMD\n", __func__); - - CopyMem (&FormatNvmCdw10, &Command->Cdw10, sizeof (NVME_ADMIN_FORMAT_NVM)); - - // - // FormatNVM Check 1: Validate SES parameter - // - if (FormatNvmCdw10.Ses > 0x2) { - Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS; - Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD; - - return EFI_INVALID_PARAMETER; - } - - // - // FormatNVM Check 2: Validate LbaIndex parameter - // - if (FormatNvmCdw10.Lbaf > 0x1) { - Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS; - Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD; - - return EFI_INVALID_PARAMETER; - } - - break; - case NVME_ADMIN_SANITIZE_CMD: - UT_LOG_VERBOSE ("%a: Opcode = NVME_ADMIN_SANITIZE_CMD\n", __func__); - - CopyMem (&SanitizeCdw1011, &Command->Cdw10, sizeof (NVME_ADMIN_SANITIZE)); - - // - // Sanitize Check 1: Validate Sanitize Action parameter - // - if (SanitizeCdw1011.Sanact > 0x4) { - Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS; - Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD; - - return EFI_INVALID_PARAMETER; - } - - // - // Sanitize Check 2: Validate overwrite action with non-NULL overwrite pattern - // - if (((SanitizeCdw1011.Sanact == SANITIZE_ACTION_OVERWRITE) && (SanitizeCdw1011.Ovrpat != 0xDEADBEEF)) || - ((SanitizeCdw1011.Sanact != SANITIZE_ACTION_OVERWRITE) && (SanitizeCdw1011.Ovrpat != 0))) - { - Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS; - Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD; - - return EFI_INVALID_PARAMETER; - } - - break; - default: - UT_LOG_VERBOSE ("%a: Invalid Opcode = 0x%x!!!\n", __func__, Command->Cdw0.Opcode); - break; - } - - // - // Populate CQE (completion queue entry based on opcode and parameters - // - - return EFI_SUCCESS; -} - -EFI_STATUS -NvmeIdentifyNamespace ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT32 NamespaceId, - IN VOID *Buffer - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD; - Command.Nsid = NamespaceId; - CommandPacket.TransferBuffer = Buffer; - CommandPacket.TransferLength = sizeof (NVME_ADMIN_NAMESPACE_DATA); - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - - // - // Set bit 0 (Cns bit) to 1 to identify a namespace - // - CommandPacket.NvmeCmd->Cdw10 = 0; - CommandPacket.NvmeCmd->Flags = CDW10_VALID; - - return EFI_SUCCESS; -} - -EFI_STATUS -NvmeUnitTestRead ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - OUT VOID *Buffer, - IN UINT64 Lba, - IN UINTN Blocks - ) -{ - UT_ASSERT_NOT_NULL (Device); - Buffer = NULL; - Lba = 0; - Blocks = 0; - - return EFI_SUCCESS; -} - -EFI_STATUS -NvmeUnitTestWrite ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - IN VOID *Buffer, - IN UINT64 Lba, - IN UINTN Blocks - ) -{ - UT_ASSERT_NOT_NULL (Device); - Buffer = NULL; - Lba = 0; - Blocks = 0; - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -NvmeBlockIoReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN IoAlign; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Media = This->Media; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - Status = NvmeUnitTestRead (Device, Buffer, Lba, NumberOfBlocks); - - return Status; -} - -EFI_STATUS -EFIAPI -NvmeBlockIoWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN IoAlign; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Media = This->Media; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - Status = NvmeUnitTestWrite (Device, Buffer, Lba, NumberOfBlocks); - - return Status; -} - -EFI_STATUS -EFIAPI -NvmeBlockIoReadBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN IoAlign; - EFI_STATUS Status; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Media = This->Media; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This); - Status = NvmeUnitTestRead (Device, Buffer, Lba, NumberOfBlocks); - - return Status; -} - -EFI_STATUS -EFIAPI -NvmeBlockIoWriteBlocksEx ( - IN EFI_BLOCK_IO2_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN OUT EFI_BLOCK_IO2_TOKEN *Token, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN IoAlign; - EFI_STATUS Status; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Media = This->Media; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This); - Status = NvmeUnitTestWrite (Device, Buffer, Lba, NumberOfBlocks); - - return Status; -} - -UNIT_TEST_STATUS -EFIAPI -NvmeDestroyDeviceInstance ( - NVME_DEVICE_PRIVATE_DATA **ppDevice - ) -{ - // - // Free in following order to to avoid dangling pointers: - // - // 1 - NVME_ADMIN_CONTROLLER_DATA - // 2 - NVME_CONTROLLER_PRIVATE_DATA - // 3 - NVME_DEVICE_PRIVATE_DATA - // - FreePool ((*ppDevice)->Controller->ControllerData); - (*ppDevice)->Controller->ControllerData = NULL; - - FreePool ((*ppDevice)->Controller); - (*ppDevice)->Controller = NULL; - - FreePool ((*ppDevice)); - *ppDevice = NULL; - - return UNIT_TEST_PASSED; -} - -UNIT_TEST_STATUS -EFIAPI -NvmeCreateDeviceInstance ( - NVME_DEVICE_PRIVATE_DATA **ppDevice - ) -{ - NVME_ADMIN_NAMESPACE_DATA *NamespaceData; - NVME_CONTROLLER_PRIVATE_DATA *Private; - NVME_DEVICE_PRIVATE_DATA *Device; - - Private = AllocateZeroPool (sizeof (NVME_CONTROLLER_PRIVATE_DATA)); - - Private->Signature = NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE; - Private->Cid[0] = 0; - Private->Cid[1] = 0; - Private->Cid[2] = 0; - Private->Pt[0] = 0; - Private->Pt[1] = 0; - Private->Pt[2] = 0; - Private->SqTdbl[0].Sqt = 0; - Private->SqTdbl[1].Sqt = 0; - Private->SqTdbl[2].Sqt = 0; - Private->CqHdbl[0].Cqh = 0; - Private->CqHdbl[1].Cqh = 0; - Private->CqHdbl[2].Cqh = 0; - Private->AsyncSqHead = 0; - - Private->ControllerData = (NVME_ADMIN_CONTROLLER_DATA *)AllocateZeroPool (sizeof (NVME_ADMIN_CONTROLLER_DATA)); - - UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_CONTROLLER_PRIVATE_DATA\n", __func__); - UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_ADMIN_CONTROLLER_DATA\n", __func__); - - Private->ControllerData->Nn = 1; // One namespace - Private->ControllerData->Sanicap.Bes = 1; // Block Erase Supported - Private->ControllerData->Sanicap.Ces = 1; // Crypto Erase Supported - Private->ControllerData->Sanicap.Ows = 1; // Overwrite Supported - - NamespaceData = AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA)); - UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_ADMIN_NAMESPACE_DATA\n", __func__); - - Device = (NVME_DEVICE_PRIVATE_DATA *)(AllocateZeroPool (sizeof (NVME_DEVICE_PRIVATE_DATA))); - - // - // Initialize SSD namespace instance data - // - Device->Signature = NVME_DEVICE_PRIVATE_DATA_SIGNATURE; - Device->NamespaceId = 0; - Device->NamespaceUuid = 1; - - Device->Controller = Private; - - // - // Build BlockIo media structure - // - Device->Media.MediaId = 0; - Device->Media.RemovableMedia = FALSE; - Device->Media.MediaPresent = TRUE; - Device->Media.LogicalPartition = FALSE; - Device->Media.ReadOnly = FALSE; - Device->Media.WriteCaching = FALSE; - Device->Media.BlockSize = (UINT32)(1 << 9); // 512 byte sector size - - Device->Media.LastBlock = 0x4000; // NamespaceData=>Nsze - Device->Media.LogicalBlocksPerPhysicalBlock = 1; - Device->Media.LowestAlignedLba = 1; - - Device->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2; - Device->BlockIo.Media = &Device->Media; - Device->BlockIo.ReadBlocks = NvmeBlockIoReadBlocks; - Device->BlockIo.WriteBlocks = NvmeBlockIoWriteBlocks; - - Device->BlockIo2.Media = &Device->Media; - Device->BlockIo2.ReadBlocksEx = NvmeBlockIoReadBlocksEx; - Device->BlockIo2.WriteBlocksEx = NvmeBlockIoWriteBlocksEx; - - Device->MediaSanitize.Revision = MEDIA_SANITIZE_PROTOCOL_REVISION; - Device->MediaSanitize.Media = &Device->Media; - Device->MediaSanitize.MediaClear = NvmExpressMediaClear; - Device->MediaSanitize.MediaPurge = NvmExpressMediaPurge; - Device->MediaSanitize.MediaFormat = NvmExpressMediaFormat; - - Device->Controller->Passthru.Mode = 0; - Device->Controller->Passthru.PassThru = NvmeDeviceUnitTestPassthru; - Device->Controller->Passthru.BuildDevicePath = NULL; - Device->Controller->Passthru.GetNamespace = NULL; - Device->Controller->Passthru.GetNextNamespace = NULL; - - CopyMem (&Device->NamespaceData, NamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA)); - *ppDevice = Device; - - UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_DEVICE_PRIVATE_DATA\n", __func__); - - return UNIT_TEST_PASSED; -} - -UNIT_TEST_STATUS -EFIAPI -MediaSanitizePurgeUnitTest ( - IN UNIT_TEST_CONTEXT Context - ) -{ - UINT32 PurgeAction; - UINT32 OverwritePattern; - UNIT_TEST_STATUS UnitTestStatus = UNIT_TEST_PASSED; - NVME_DEVICE_PRIVATE_DATA *NvmeDevice = NULL; - EFI_STATUS Status = EFI_SUCCESS; - - UnitTestStatus = NvmeCreateDeviceInstance (&NvmeDevice); - - UT_ASSERT_STATUS_EQUAL (UnitTestStatus, UNIT_TEST_PASSED); - UT_ASSERT_NOT_NULL (NvmeDevice); - - UT_LOG_VERBOSE ("%a: Create Device Instance Status = 0x%x\n", __func__, UnitTestStatus); - UT_LOG_VERBOSE ("%a: Device = 0x%x\n", __func__, NvmeDevice); - UT_LOG_VERBOSE ("%a: Device->BlockIo = 0x%x\n", __func__, NvmeDevice->BlockIo); - UT_LOG_VERBOSE ("%a: Device->Signature = 0x%x\n", __func__, NvmeDevice->Signature); - - // - // Case 1: Block Erase - // - PurgeAction = SANITIZE_ACTION_BLOCK_ERASE; - OverwritePattern = 0; - - Status = NvmExpressMediaPurge ( - &NvmeDevice->MediaSanitize, - NvmeDevice->Media.MediaId, - PurgeAction, - OverwritePattern - ); - - UT_ASSERT_NOT_EFI_ERROR (Status); - - UnitTestStatus = NvmeDestroyDeviceInstance (&NvmeDevice); - - return UNIT_TEST_PASSED; -} - -UNIT_TEST_STATUS -EFIAPI -NvmeSanitizeUnitTest ( - IN UNIT_TEST_CONTEXT Context - ) -{ - UINT32 NamespaceId = 0; - UINT32 SanitizeAction; - UINT32 NoDeallocateAfterSanitize; - UINT32 OverwritePattern; - UNIT_TEST_STATUS UnitTestStatus = UNIT_TEST_PASSED; - NVME_DEVICE_PRIVATE_DATA *NvmeDevice = NULL; - EFI_STATUS Status = EFI_SUCCESS; - - SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE; - NoDeallocateAfterSanitize = 0; - OverwritePattern = 0; - - UnitTestStatus = NvmeCreateDeviceInstance (&NvmeDevice); - - UT_ASSERT_STATUS_EQUAL (UnitTestStatus, UNIT_TEST_PASSED); - UT_ASSERT_NOT_NULL (NvmeDevice); - - UT_LOG_VERBOSE ("%a: Create Device Instance Status = 0x%x\n", __func__, UnitTestStatus); - UT_LOG_VERBOSE ("%a: Device = 0x%x\n", __func__, NvmeDevice); - UT_LOG_VERBOSE ("%a: Device->BlockIo = 0x%x\n", __func__, NvmeDevice->BlockIo); - UT_LOG_VERBOSE ("%a: Device->Signature = 0x%x\n", __func__, NvmeDevice->Signature); - - // - // Case 1: Block Erase - // - SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE; - NoDeallocateAfterSanitize = 0; - OverwritePattern = 0; - - Status = NvmExpressSanitize ( - &NvmeDevice->BlockIo, - NamespaceId, - SanitizeAction, - NoDeallocateAfterSanitize, - OverwritePattern - ); - - UT_ASSERT_NOT_EFI_ERROR (Status); - - // - // Case 2: Crypto Erase - // - SanitizeAction = SANITIZE_ACTION_CRYPTO_ERASE; - NoDeallocateAfterSanitize = 0; - OverwritePattern = 0; - - Status = NvmExpressSanitize ( - &NvmeDevice->BlockIo, - NamespaceId, - SanitizeAction, - NoDeallocateAfterSanitize, - OverwritePattern - ); - - UT_ASSERT_NOT_EFI_ERROR (Status); - - // - // Case 3: Overwrite - // - SanitizeAction = SANITIZE_ACTION_OVERWRITE; - NoDeallocateAfterSanitize = 0; - OverwritePattern = 0xDEADBEEF; - - Status = NvmExpressSanitize ( - &NvmeDevice->BlockIo, - NamespaceId, - SanitizeAction, - NoDeallocateAfterSanitize, - OverwritePattern - ); - - UT_ASSERT_NOT_EFI_ERROR (Status); - - // - // Case 4: Block Erase (invalid overwrite pattern) - // - SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE; - NoDeallocateAfterSanitize = 0; - OverwritePattern = 0xDEADBEEF; - - Status = NvmExpressSanitize ( - &NvmeDevice->BlockIo, - NamespaceId, - SanitizeAction, - NoDeallocateAfterSanitize, - OverwritePattern - ); - - UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); - - // - // Case 5: Overwrite (invalid overwrite pattern) - // - SanitizeAction = SANITIZE_ACTION_OVERWRITE; - NoDeallocateAfterSanitize = 0; - OverwritePattern = 0; - - Status = NvmExpressSanitize ( - &NvmeDevice->BlockIo, - NamespaceId, - SanitizeAction, - NoDeallocateAfterSanitize, - OverwritePattern - ); - - UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); - - UnitTestStatus = NvmeDestroyDeviceInstance (&NvmeDevice); - - return UNIT_TEST_PASSED; -} - -UNIT_TEST_STATUS -EFIAPI -NvmeFormatNvmUnitTest ( - IN UNIT_TEST_CONTEXT Context - ) -{ - UINT32 NamespaceId = 0; - UINT32 Ses; - UINT32 Flbas; - NVME_DEVICE_PRIVATE_DATA *NvmeDevice = NULL; - UNIT_TEST_STATUS UnitTestStatus = UNIT_TEST_PASSED; - EFI_STATUS Status = EFI_SUCCESS; - - UnitTestStatus = NvmeCreateDeviceInstance (&NvmeDevice); - - UT_ASSERT_STATUS_EQUAL (UnitTestStatus, UNIT_TEST_PASSED); - UT_ASSERT_NOT_NULL (NvmeDevice); - - UT_LOG_VERBOSE ("%a: Create Device Instance Status = 0x%x\n", __func__, UnitTestStatus); - UT_LOG_VERBOSE ("%a: Device = 0x%x\n", __func__, NvmeDevice); - UT_LOG_VERBOSE ("%a: Device->BlockIo = 0x%x\n", __func__, NvmeDevice->BlockIo); - UT_LOG_VERBOSE ("%a: Device->Signature = 0x%x\n", __func__, NvmeDevice->Signature); - - // - // Case 1: User Data Erase (Flbas = 0) - // - Ses = SES_USER_DATA_ERASE; - Flbas = 0; - Status = NvmExpressFormatNvm ( - &NvmeDevice->BlockIo, - NamespaceId, - Ses, - Flbas - ); - - UT_ASSERT_NOT_EFI_ERROR (Status); - - // - // Case 2: Crypto Erase (Flbas = 0) - // - Ses = SES_CRYPTO_ERASE; - Flbas = 0; - Status = NvmExpressFormatNvm ( - &NvmeDevice->BlockIo, - NamespaceId, - Ses, - Flbas - ); - - UT_ASSERT_NOT_EFI_ERROR (Status); - - // - // Case 3: User Data Erase (Invalid Flbas = 3) - // - Ses = SES_USER_DATA_ERASE; - Flbas = 3; - Status = NvmExpressFormatNvm ( - &NvmeDevice->BlockIo, - NamespaceId, - Ses, - Flbas - ); - - UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); - - // - // Case 4: Invalid SES (Flba = 0) - // - Ses = 0xFF; - Flbas = 0; - Status = NvmExpressFormatNvm ( - &NvmeDevice->BlockIo, - NamespaceId, - Ses, - Flbas - ); - - UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); - - UnitTestStatus = NvmeDestroyDeviceInstance (&NvmeDevice); - - return UNIT_TEST_PASSED; -} - -UNIT_TEST_STATUS -EFIAPI -UnitTestBaseline ( - IN UNIT_TEST_CONTEXT Context - ) -{ - UINT32 A; - UINT32 B; - UINT32 C; - - A = 1; - B = 1; - C = A + B; - - UT_ASSERT_EQUAL (C, 2); - UT_ASSERT_NOT_EQUAL (0, 1); - - return UNIT_TEST_PASSED; -} - -EFI_STATUS -EFIAPI -MediaSanitizeUnitTestEntry ( - VOID - ) -{ - EFI_STATUS Status; - UNIT_TEST_FRAMEWORK_HANDLE Framework; - UNIT_TEST_SUITE_HANDLE NvmeFormatNvmTestSuite; - UNIT_TEST_SUITE_HANDLE NvmeSanitizeTestSuite; - UNIT_TEST_SUITE_HANDLE MediaSanitizeProtocolTestSuite; - - Framework = NULL; - - #define UNIT_TEST_NAME "Media Sanitize Protocol Unit Test" - #define UNIT_TEST_VERSION "1.0" - - DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); - - // - // Start setting up the test framework for running the tests. - // - Status = InitUnitTestFramework ( - &Framework, - UNIT_TEST_NAME, - gEfiCallerBaseName, - UNIT_TEST_VERSION - ); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); - goto EXIT; - } - - // - // Populate the NVM Express Format NVM Unit Test Suite. - // - Status = CreateUnitTestSuite ( - &NvmeFormatNvmTestSuite, - Framework, - "NVM Express Format NVM Test Suite", - "Nvm.Express.Format.Nvm", - NULL, - NULL - ); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for NvmeFormatNvmTestSuite. Status = %r\n", Status)); - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } - - // - // Add baseline sanity test case - // - AddTestCase ( - NvmeFormatNvmTestSuite, // Test Suite Handle - "Baseline Format NVM Unit Test", // Test Description - "FormatNVM", // Test Class - UnitTestBaseline, // UNIT_TEST_FUNCTION() - NULL, // (Optional) UNIT_TEST_PREREQUISITE() - NULL, // (Optional) UNIT_TEST_CLEANUP() - NULL // (Optional) UNIT_TEST_CONTEXT - ); - - // - // Add test case for NvmExpressFormatNvm() - // - AddTestCase ( - NvmeFormatNvmTestSuite, // Test Suite Handle - "Admin Format NVM Command Unit Test", // Test Description - "FormatNVM", // Test Class - NvmeFormatNvmUnitTest, // UNIT_TEST_FUNCTION() - NULL, // (Optional) UNIT_TEST_PREREQUISITE() - NULL, // (Optional) UNIT_TEST_CLEANUP() - NULL // (Optional) UNIT_TEST_CONTEXT - ); - - // - // Populate the NVM Express Sanitize Unit Test Suite. - // - Status = CreateUnitTestSuite ( - &NvmeSanitizeTestSuite, - Framework, - "NVM Express Sanitize Test Suite", - "Nvm.Express.Sanitize", - NULL, - NULL - ); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for NvmeSanitizTestSuite. Status = %r\n", Status)); - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } - - // - // Add baseline sanity test - // - AddTestCase ( - NvmeSanitizeTestSuite, // Test Suite Handle - "Baseline Sanitize Unit Test", // Test Description - "Sanitize", // Test Class - UnitTestBaseline, // UNIT_TEST_FUNCTION() - NULL, // (Optional) UNIT_TEST_PREREQUISITE() - NULL, // (Optional) UNIT_TEST_CLEANUP() - NULL // (Optional) UNIT_TEST_CONTEXT - ); - - // - // Add test case for NvmExressSanitize() - // - AddTestCase ( - NvmeSanitizeTestSuite, // Test Suite Handle - "Admin Sanitize Command Unit Test", // Test Description - "Sanitize", // Test Class - NvmeSanitizeUnitTest, // UNIT_TEST_FUNCTION() - NULL, // (Optional) UNIT_TEST_PREREQUISITE() - NULL, // (Optional) UNIT_TEST_CLEANUP() - NULL // (Optional) UNIT_TEST_CONTEXT - ); - - // - // Populate the Media Sanitize Protocol Unit Test Suite. - // - Status = CreateUnitTestSuite ( - &MediaSanitizeProtocolTestSuite, - Framework, - "Media Sanitize Protocol Test Suite", - "Media.Sanitize.Protocol", - NULL, - NULL - ); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MediaSanitizeProtocolTestSuite. Status = %r\n", Status)); - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } - - // - // Add test case for Media Purge - // - AddTestCase ( - MediaSanitizeProtocolTestSuite, // Test Suite Handle - "Baseline MediaSanitize Unit Test", // Test Description - "MediaSanitize", // Test Class - UnitTestBaseline, // UNIT_TEST_FUNCTION() - NULL, // (Optional) UNIT_TEST_PREREQUISITE() - NULL, // (Optional) UNIT_TEST_CLEANUP() - NULL // (Optional) UNIT_TEST_CONTEXT - ); - - // - // Add test case for Media Purge - // - AddTestCase ( - MediaSanitizeProtocolTestSuite, // Test Suite Handle - "Protocol Media Sanitize Unit Test", // Test Description - "MediaPurge", // Test Class - MediaSanitizePurgeUnitTest, // UNIT_TEST_FUNCTION() - NULL, // (Optional) UNIT_TEST_PREREQUISITE() - NULL, // (Optional) UNIT_TEST_CLEANUP() - NULL // (Optional) UNIT_TEST_CONTEXT - ); - - // - // Execute the tests. - // - Status = RunAllTestSuites (Framework); - -EXIT: - if (Framework) { - FreeUnitTestFramework (Framework); - } - - return Status; -} - -int -main ( - int argc, - char *argv[] - ) -{ - return MediaSanitizeUnitTestEntry (); -} diff --git a/MsvmPkg/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf b/MsvmPkg/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf deleted file mode 100644 index 0997ef0e30..0000000000 --- a/MsvmPkg/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf +++ /dev/null @@ -1,37 +0,0 @@ -## @file -# Unit tests for MEDIA_SANITIZE_PROTOCOL and mapping to NVM Express native commands (Sanitize and FormatNVM) -# -# Copyright (C) Microsoft Corporation. -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x00010006 - BASE_NAME = MediaSanitizeUnitTestHost - FILE_GUID = AAE328E9-37C3-4F4A-A2C0-0BE0E681ADA6 - MODULE_TYPE = HOST_APPLICATION - VERSION_STRING = 1.0 - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - MediaSanitizeUnitTest.c - ../NvmExpressMediaSanitize.c - ../NvmExpressMediaSanitize.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - UnitTestLib - PrintLib - MemoryAllocationLib diff --git a/MsvmPkg/VpcivscDxe/VpcivscDxe.inf b/MsvmPkg/VpcivscDxe/VpcivscDxe.inf index f0c085cbba..898ebee89b 100644 --- a/MsvmPkg/VpcivscDxe/VpcivscDxe.inf +++ b/MsvmPkg/VpcivscDxe/VpcivscDxe.inf @@ -19,6 +19,7 @@ [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec MsvmPkg/MsvmPkg.dec [LibraryClasses] @@ -29,6 +30,7 @@ DevicePathLib EmclLib IoLib + IoMmuLib IsolationLib MemoryAllocationLib MmioAllocationLib diff --git a/MsvmPkg/VpcivscDxe/VpcivscPciIo.c b/MsvmPkg/VpcivscDxe/VpcivscPciIo.c index 565655d369..262f3fcab2 100644 --- a/MsvmPkg/VpcivscDxe/VpcivscPciIo.c +++ b/MsvmPkg/VpcivscDxe/VpcivscPciIo.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -581,10 +582,44 @@ VpcivscPciIoMap( OUT VOID **Mapping ) { - // For VPCI, the VSC has DMA access to all pages. So nothing to do here, - // just return the address of the buffer. + if (IoMmuIsPresent ()) { + // + // Isolated VM: delegate to the IOMMU protocol for bounce buffering. + // EFI_PCI_IO_PROTOCOL_OPERATION maps directly to EDKII_IOMMU_OPERATION + // because the BusMasterRead / BusMasterWrite / BusMasterCommonBuffer + // members share the same ordinal values (0, 1, 2) in both enums. + // The STATIC_ASSERTs below catch any future divergence at compile time. + // + STATIC_ASSERT ( + (UINT32)EfiPciIoOperationBusMasterRead == + (UINT32)EdkiiIoMmuOperationBusMasterRead, + "EFI_PCI_IO_PROTOCOL_OPERATION/EDKII_IOMMU_OPERATION BusMasterRead mismatch" + ); + STATIC_ASSERT ( + (UINT32)EfiPciIoOperationBusMasterWrite == + (UINT32)EdkiiIoMmuOperationBusMasterWrite, + "EFI_PCI_IO_PROTOCOL_OPERATION/EDKII_IOMMU_OPERATION BusMasterWrite mismatch" + ); + STATIC_ASSERT ( + (UINT32)EfiPciIoOperationBusMasterCommonBuffer == + (UINT32)EdkiiIoMmuOperationBusMasterCommonBuffer, + "EFI_PCI_IO_PROTOCOL_OPERATION/EDKII_IOMMU_OPERATION BusMasterCommonBuffer mismatch" + ); + + return IoMmuMap ( + (EDKII_IOMMU_OPERATION)Operation, + HostAddress, + NumberOfBytes, + DeviceAddress, + Mapping + ); + } - *DeviceAddress = (UINTN) HostAddress; + // + // No IoMmu bounce case: the VSC has DMA access to all pages. + // Just return the address of the buffer. + // + *DeviceAddress = (UINTN)HostAddress; *Mapping = NULL; return EFI_SUCCESS; @@ -606,10 +641,11 @@ VpcivscPciIoUnmap( IN VOID *Mapping ) { - // DEBUG((DEBUG_VPCI_INFO, "VpcivscPciIoUnmap called with mapping %llx\n", Mapping)); - - ASSERT(Mapping == NULL); + if (IoMmuIsPresent ()) { + return IoMmuUnmap (Mapping); + } + // No IoMmu bounce case: nothing to do since Map is a noop. return EFI_SUCCESS; } @@ -644,36 +680,37 @@ VpcivscPciIoAllocateBuffer( IN UINT64 Attributes ) { - VOID* buffer = NULL; - - DEBUG((DEBUG_VPCI_INFO, "VpcivscPciIoAllocateBuffer called with pages %x\n", Pages)); - - // For VPCI, the VSC has DMA access to all pages. So nothing special here, - // just allocate memory like normal. + DEBUG ((DEBUG_VPCI_INFO, "VpcivscPciIoAllocateBuffer called with pages %x\n", Pages)); + + if (IoMmuIsPresent ()) { + // + // Isolated VM: delegate to the IOMMU protocol which allocates + // host-visible memory and returns a shared VA. + // + return IoMmuAllocateBuffer (Type, MemoryType, Pages, HostAddress, Attributes); + } - // NVMe dxe driver doesn't use attributes. + // + // Non-isolated VM: just allocate memory normally. + // if (Attributes != 0) { - ASSERT(FALSE); + ASSERT (FALSE); return EFI_UNSUPPORTED; } if (MemoryType != EfiBootServicesData) { - ASSERT(FALSE); + ASSERT (FALSE); return EFI_UNSUPPORTED; } - buffer = AllocatePages(Pages); - - if (buffer == NULL) + *HostAddress = AllocatePages (Pages); + if (*HostAddress == NULL) { return EFI_OUT_OF_RESOURCES; } - // The host address is just the buffer address. No special mapping. - *HostAddress = buffer; - return EFI_SUCCESS; } @@ -685,14 +722,17 @@ VpcivscPciIoFreeBuffer( IN VOID *HostAddress ) { - DEBUG((DEBUG_VPCI_INFO, "VpcivscPciIoFreeBuffer called with addr %llx pages %x\n", HostAddress, Pages)); - - // Free the buffer allocated with AllocatePages - // FreePages(HostAddress, Pages); - // NOTE: To workaround a bug with ND2 on the host registering write - // notifications for pages resulting in the VM hanging, do not put - // pages used for NVMe queues back onto the free list. Instead, - // leak these pages as they will be reclaimed later at ExitBootServices. + DEBUG ((DEBUG_VPCI_INFO, "VpcivscPciIoFreeBuffer called with addr %llx pages %x\n", HostAddress, Pages)); + + if (IoMmuIsPresent ()) { + // + // Isolated VM: delegate to the IOMMU protocol which revokes + // host visibility and frees the pages. + // + return IoMmuFreeBuffer (Pages, HostAddress); + } + + FreePages (HostAddress, Pages); return EFI_SUCCESS; }