From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.81]) by mx.groups.io with SMTP id smtpd.web10.10550.1574769558764963161 for ; Tue, 26 Nov 2019 03:59:19 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=QgGO3r1O; spf=pass (domain: redhat.com, ip: 207.211.31.81, mailfrom: philmd@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1574769557; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZTUatFnEMTHUGpn0gdMRPNWidaonKaZ4LkOt45QerwQ=; b=QgGO3r1O+jorbDGjfUyuiart7MJumAxMZA+tNcstuABoYHygnZ3blPtZV7Ql254WOuHcRe b7SSIKdBN7PcqGpKRGd5JV/+VjNtSCDlXaKVx/+h8QGb9xIJXGVW+A3UqKLAc7xk72Qv8M +HuQH8/q/FOGOtW/xMiND8qEgIsiaVo= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-145-GX2WxiJ5PVexcT1hfpDZ6A-1; Tue, 26 Nov 2019 06:59:16 -0500 Received: by mail-wr1-f69.google.com with SMTP id q6so10414924wrv.11 for ; Tue, 26 Nov 2019 03:59:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:references:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=UyuWvPXcn/PKDhKvhcDjGHzOU3mmkQ1lvs/uEwVbqIw=; b=XlC+g1oxAIhrygTAkQWdZD/FiIgReFRUiLJkxTxLjIhAI/S4e3M7iynp2f2Iazmuv5 N+pNUZ77e3fBiCKVXwiBZBMTgF1Y66FUMR241amKWQ6vGG6LXtgoojcILDXnKaLD+Nlr mTSjBG9KEXexJL/GFkseLeBn2TTfvgRdFnRGUhN/DG+Fr5UhpELeG31tNr82ZRpdgMDj KyEFewVqVRzKZniDHf3+SJrBiE9ENaUZ8asUlZZu5NfN26ifBEBFfKF1lc7zEAU7qei9 OnWj1aEvbEJowQZ3CUKmFcoo5F/jbHWhcB90FYOW3mhx2jlm6G/BMhQTuspjREQxwGpi QKAg== X-Gm-Message-State: APjAAAUjBPU1IgEadlTgsVkRQeaZaXpNeyMYk1AB2QFfzBMOA0m6/I7G eJlOZfJl8iKniIxcQHbEhp/fTfY55LU5zTVdSVKC7D7flHAMEmPG4aEYWZsgS61MWmWoMYwVnAD OarflKogVVLtLwA== X-Received: by 2002:a5d:444a:: with SMTP id x10mr36730761wrr.228.1574769554878; Tue, 26 Nov 2019 03:59:14 -0800 (PST) X-Google-Smtp-Source: APXvYqxXw3PaLJpOMtjzEdxRFtmT5t+ljusK/pYucoeF30exZpP8x2joQ6E8LHY9Hr51dAZbv+D+Gw== X-Received: by 2002:a5d:444a:: with SMTP id x10mr36730736wrr.228.1574769554496; Tue, 26 Nov 2019 03:59:14 -0800 (PST) Return-Path: Received: from [192.168.1.35] (182.red-88-21-103.staticip.rima-tde.net. [88.21.103.182]) by smtp.gmail.com with ESMTPSA id k1sm15049126wrp.29.2019.11.26.03.59.13 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 26 Nov 2019 03:59:13 -0800 (PST) Subject: Re: [edk2-devel] [PATCH v2 1/2] EmbeddedPkg/NonCoherentDmaLib: implement support for DMA range limits From: =?UTF-8?B?UGhpbGlwcGUgTWF0aGlldS1EYXVkw6k=?= To: devel@edk2.groups.io, ard.biesheuvel@linaro.org Cc: leif.lindholm@linaro.org References: <20191125231242.12193-1-ard.biesheuvel@linaro.org> <20191125231242.12193-2-ard.biesheuvel@linaro.org> Message-ID: <08876497-a2ce-4b55-6f50-f332ffd45ddd@redhat.com> Date: Tue, 26 Nov 2019 12:59:12 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.1.1 MIME-Version: 1.0 In-Reply-To: X-MC-Unique: GX2WxiJ5PVexcT1hfpDZ6A-1 X-Mimecast-Spam-Score: 0 Content-Language: en-US Content-Type: text/plain; charset=WINDOWS-1252; format=flowed Content-Transfer-Encoding: quoted-printable On 11/26/19 11:44 AM, Philippe Mathieu-Daud=E9 wrote: > On 11/26/19 12:12 AM, Ard Biesheuvel via Groups.Io wrote: >> Implement support for driving peripherals with limited DMA ranges to >> NonCoherentDmaLib, by adding a device address limit, and taking it, >> along with the device offset, into account when allocating or mapping >> DMA buffers. >> >> Signed-off-by: Ard Biesheuvel >> --- >> =A0 EmbeddedPkg/EmbeddedPkg.dec=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 |=A0=A0 6 + >> =A0 EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c=A0=A0 | 16= 5=20 >> ++++++++++++++++++-- >> =A0 EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf |=A0=A0 = 1 + >> =A0 3 files changed, 160 insertions(+), 12 deletions(-) >> >> diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec >> index 8812a6db7c30..69922802f473 100644 >> --- a/EmbeddedPkg/EmbeddedPkg.dec >> +++ b/EmbeddedPkg/EmbeddedPkg.dec >> @@ -186,6 +186,12 @@ [PcdsFixedAtBuild.common, PcdsDynamic.common] >> =A0=A0=A0 # >> =A0=A0=A0 gEmbeddedTokenSpaceGuid.PcdDmaDeviceOffset|0x0|UINT64|0x000005= 8 >> +=A0 # >> +=A0 # Highest address value supported by the device for DMA addressing.= =20 >> Note >> +=A0 # that this value should be strictly greater than PcdDmaDeviceOffse= t. >> +=A0 # >> + =20 >> gEmbeddedTokenSpaceGuid.PcdDmaDeviceLimit|0xFFFFFFFFFFFFFFFF|UINT64|0x00= 0005A=20 >> >> + >> =A0=A0=A0 # >> =A0=A0=A0 # Selection between DT and ACPI as a default >> =A0=A0=A0 # >> diff --git a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c= =20 >> b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c >> index 78220f6358aa..115345765435 100644 >> --- a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c >> +++ b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c >> @@ -40,6 +40,8 @@ typedef struct { >> =A0 STATIC EFI_CPU_ARCH_PROTOCOL=A0=A0=A0=A0=A0 *mCpu; >> =A0 STATIC LIST_ENTRY=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Un= cachedAllocationList; >> +STATIC PHYSICAL_ADDRESS=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 mDmaHostAddressLi= mit; >> + >> =A0 STATIC >> =A0 PHYSICAL_ADDRESS >> =A0 HostToDeviceAddress ( >> @@ -49,6 +51,102 @@ HostToDeviceAddress ( >> =A0=A0=A0 return (PHYSICAL_ADDRESS)(UINTN)Address + PcdGet64=20 >> (PcdDmaDeviceOffset); >> =A0 } >> +/** >> +=A0 Allocates one or more 4KB pages of a certain memory type at a=20 >> specified >> +=A0 alignment. >> + >> +=A0 Allocates the number of 4KB pages specified by Pages of a certain= =20 >> memory type >> +=A0 with an alignment specified by Alignment. The allocated buffer is= =20 >> returned. >> +=A0 If Pages is 0, then NULL is returned. If there is not enough memory= =20 >> at the >> +=A0 specified alignment remaining to satisfy the request, then NULL is= =20 >> returned. >> +=A0 If Alignment is not a power of two and Alignment is not zero, then= =20 >> ASSERT(). >> +=A0 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(= ). >> + >> +=A0 @param=A0 MemoryType=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 The type of m= emory to allocate. >> +=A0 @param=A0 Pages=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 The= number of 4 KB pages to allocate. >> +=A0 @param=A0 Alignment=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 The request= ed alignment of the=20 >> allocation. >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0 Must be a power of two. >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0 If Alignment is zero, then byte=20 >> alignment is >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0 used. >> + >> +=A0 @return A pointer to the allocated buffer or NULL if allocation fai= ls. >> + >> +**/ >> +STATIC >> +VOID * >> +InternalAllocateAlignedPages ( >> +=A0 IN EFI_MEMORY_TYPE=A0 MemoryType, >> +=A0 IN UINTN=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Pages, >> +=A0 IN UINTN=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Alignment >> +=A0 ) >> +{ >> +=A0 EFI_STATUS=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Status; >> +=A0 EFI_PHYSICAL_ADDRESS=A0 Memory; >> +=A0 UINTN=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 AlignedMemory= ; >> +=A0 UINTN=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 AlignmentMask= ; >> +=A0 UINTN=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 UnalignedPage= s; >> +=A0 UINTN=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 RealPages; >> + >> +=A0 // >> +=A0 // Alignment must be a power of two or zero. >> +=A0 // >> +=A0 ASSERT ((Alignment & (Alignment - 1)) =3D=3D 0); >> + >> +=A0 if (Pages =3D=3D 0) { >> +=A0=A0=A0 return NULL; >> +=A0 } >> +=A0 if (Alignment > EFI_PAGE_SIZE) { >> +=A0=A0=A0 // >> +=A0=A0=A0 // Calculate the total number of pages since alignment is lar= ger=20 >> than page >> +=A0=A0=A0 // size. >> +=A0=A0=A0 // >> +=A0=A0=A0 AlignmentMask=A0 =3D Alignment - 1; >> +=A0=A0=A0 RealPages=A0=A0=A0=A0=A0 =3D Pages + EFI_SIZE_TO_PAGES (Align= ment); >> +=A0=A0=A0 // >> +=A0=A0=A0 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) do= es not >> +=A0=A0=A0 // overflow. >> +=A0=A0=A0 // >> +=A0=A0=A0 ASSERT (RealPages > Pages); >> + >> +=A0=A0=A0 Memory =3D mDmaHostAddressLimit; >> +=A0=A0=A0 Status =3D gBS->AllocatePages (AllocateMaxAddress, MemoryType= ,=20 >> RealPages, >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 &Memory); >> +=A0=A0=A0 if (EFI_ERROR (Status)) { >> +=A0=A0=A0=A0=A0 return NULL; >> +=A0=A0=A0 } >> +=A0=A0=A0 AlignedMemory=A0 =3D ((UINTN)Memory + AlignmentMask) & ~Align= mentMask; >> +=A0=A0=A0 UnalignedPages =3D EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)= Memory); The previous line made me think twice (due to the cast), but I can't=20 find a simpler way to write the same code. >> +=A0=A0=A0 if (UnalignedPages > 0) { >> +=A0=A0=A0=A0=A0 // >> +=A0=A0=A0=A0=A0 // Free first unaligned page(s). >> +=A0=A0=A0=A0=A0 // >> +=A0=A0=A0=A0=A0 Status =3D gBS->FreePages (Memory, UnalignedPages); >> +=A0=A0=A0=A0=A0 ASSERT_EFI_ERROR (Status); >> +=A0=A0=A0 } >> +=A0=A0=A0 Memory=A0=A0=A0=A0=A0=A0=A0=A0 =3D AlignedMemory + EFI_PAGES_= TO_SIZE (Pages); >> +=A0=A0=A0 UnalignedPages =3D RealPages - Pages - UnalignedPages; >> +=A0=A0=A0 if (UnalignedPages > 0) { >> +=A0=A0=A0=A0=A0 // >> +=A0=A0=A0=A0=A0 // Free last unaligned page(s). >> +=A0=A0=A0=A0=A0 // >> +=A0=A0=A0=A0=A0 Status =3D gBS->FreePages (Memory, UnalignedPages); >> +=A0=A0=A0=A0=A0 ASSERT_EFI_ERROR (Status); >> +=A0=A0=A0 } >> +=A0 } else { >> +=A0=A0=A0 // >> +=A0=A0=A0 // Do not over-allocate pages in this case. >> +=A0=A0=A0 // >> +=A0=A0=A0 Memory =3D mDmaHostAddressLimit; >> +=A0=A0=A0 Status =3D gBS->AllocatePages (AllocateMaxAddress, MemoryType= , Pages, >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 &Memory); >> +=A0=A0=A0 if (EFI_ERROR (Status)) { >> +=A0=A0=A0=A0=A0 return NULL; >> +=A0=A0=A0 } >> +=A0=A0=A0 AlignedMemory =3D (UINTN)Memory; >> +=A0 } >> +=A0 return (VOID *)AlignedMemory; >> +} >> + >> =A0 /** >> =A0=A0=A0 Provides the DMA controller-specific addresses needed to acces= s=20 >> system memory. >> @@ -111,7 +209,30 @@ DmaMap ( >> =A0=A0=A0=A0=A0 return=A0 EFI_OUT_OF_RESOURCES; >> =A0=A0=A0 } >> -=A0 if (Operation !=3D MapOperationBusMasterRead && >> +=A0 if (((UINTN)HostAddress + *NumberOfBytes) > mDmaHostAddressLimit) { >> + >> +=A0=A0=A0 if (Operation =3D=3D MapOperationBusMasterCommonBuffer) { >> +=A0=A0=A0=A0=A0 goto CommonBufferError; >> +=A0=A0=A0 } >> + >> +=A0=A0=A0 AllocSize =3D ALIGN_VALUE (*NumberOfBytes, mCpu->DmaBufferAli= gnment); >> +=A0=A0=A0 Map->BufferAddress =3D InternalAllocateAlignedPages=20 >> (EfiBootServicesData, >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 EFI_SIZE_TO_PAGES (AllocSize), >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 mCpu->DmaBufferAlignment); >> +=A0=A0=A0 if (Map->BufferAddress =3D=3D NULL) { >> +=A0=A0=A0=A0=A0 Status =3D EFI_OUT_OF_RESOURCES; >> +=A0=A0=A0=A0=A0 goto FreeMapInfo; >> +=A0=A0=A0 } >> + >> +=A0=A0=A0 if (Map->Operation =3D=3D MapOperationBusMasterRead) { >> +=A0=A0=A0=A0=A0 CopyMem (Map->BufferAddress, (VOID *)(UINTN)Map->HostAd= dress, >> +=A0=A0=A0=A0=A0=A0=A0 *NumberOfBytes); >> +=A0=A0=A0 } >> +=A0=A0=A0 mCpu->FlushDataCache (mCpu, (UINTN)Map->BufferAddress, AllocS= ize, >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 EfiCpuFlushTypeWriteBack); >> + >> +=A0=A0=A0 *DeviceAddress =3D HostToDeviceAddress (Map->BufferAddress); >> +=A0 } else if (Operation !=3D MapOperationBusMasterRead && >> =A0=A0=A0=A0=A0=A0=A0 ((((UINTN)HostAddress & (mCpu->DmaBufferAlignment = - 1)) !=3D 0) || >> =A0=A0=A0=A0=A0=A0=A0=A0 ((*NumberOfBytes & (mCpu->DmaBufferAlignment - = 1)) !=3D 0))) { >> @@ -128,12 +249,7 @@ DmaMap ( >> =A0=A0=A0=A0=A0=A0=A0 // on uncached buffers. >> =A0=A0=A0=A0=A0=A0=A0 // >> =A0=A0=A0=A0=A0=A0=A0 if (Operation =3D=3D MapOperationBusMasterCommonBu= ffer) { >> -=A0=A0=A0=A0=A0=A0=A0 DEBUG ((DEBUG_ERROR, >> -=A0=A0=A0=A0=A0=A0=A0=A0=A0 "%a: Operation type 'MapOperationBusMasterC= ommonBuffer' is=20 >> only " >> -=A0=A0=A0=A0=A0=A0=A0=A0=A0 "supported\non memory regions that were all= ocated using " >> -=A0=A0=A0=A0=A0=A0=A0=A0=A0 "DmaAllocateBuffer ()\n", __FUNCTION__)); >> -=A0=A0=A0=A0=A0=A0=A0 Status =3D EFI_UNSUPPORTED; >> -=A0=A0=A0=A0=A0=A0=A0 goto FreeMapInfo; >> +=A0=A0=A0=A0=A0=A0=A0 goto CommonBufferError; >> =A0=A0=A0=A0=A0=A0=A0 } >> =A0=A0=A0=A0=A0=A0=A0 // >> @@ -199,6 +315,12 @@ DmaMap ( >> =A0=A0=A0 return EFI_SUCCESS; >> +CommonBufferError: >> +=A0 DEBUG ((DEBUG_ERROR, >> +=A0=A0=A0 "%a: Operation type 'MapOperationBusMasterCommonBuffer' is on= ly " >> +=A0=A0=A0 "supported\non memory regions that were allocated using " >> +=A0=A0=A0 "DmaAllocateBuffer ()\n", __FUNCTION__)); >> +=A0 Status =3D EFI_UNSUPPORTED; >> =A0 FreeMapInfo: >> =A0=A0=A0 FreePool (Map); >> @@ -229,6 +351,7 @@ DmaUnmap ( >> =A0=A0=A0 MAP_INFO_INSTANCE *Map; >> =A0=A0=A0 EFI_STATUS=A0=A0=A0=A0=A0=A0=A0 Status; >> =A0=A0=A0 VOID=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 *Buffer; >> +=A0 UINTN=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 AllocSize; >> =A0=A0=A0 if (Mapping =3D=3D NULL) { >> =A0=A0=A0=A0=A0 ASSERT (FALSE); >> @@ -238,7 +361,17 @@ DmaUnmap ( >> =A0=A0=A0 Map =3D (MAP_INFO_INSTANCE *)Mapping; >> =A0=A0=A0 Status =3D EFI_SUCCESS; >> -=A0 if (Map->DoubleBuffer) { >> +=A0 if (((UINTN)Map->HostAddress + Map->NumberOfBytes) >=20 >> mDmaHostAddressLimit) { >> +=A0=A0=A0 AllocSize =3D ALIGN_VALUE (Map->NumberOfBytes,=20 >> mCpu->DmaBufferAlignment); >> +=A0=A0=A0 if (Map->Operation =3D=3D MapOperationBusMasterWrite) { >> +=A0=A0=A0=A0=A0 mCpu->FlushDataCache (mCpu, (UINTN)Map->BufferAddress, = AllocSize, >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 EfiCpuFlushTypeInvalidate); >> +=A0=A0=A0=A0=A0 CopyMem ((VOID *)(UINTN)Map->HostAddress, Map->BufferAd= dress, >> +=A0=A0=A0=A0=A0=A0=A0 Map->NumberOfBytes); >> +=A0=A0=A0 } >> +=A0=A0=A0 FreePages (Map->BufferAddress, EFI_SIZE_TO_PAGES (AllocSize))= ; >> +=A0 } else if (Map->DoubleBuffer) { >> + >> =A0=A0=A0=A0=A0 ASSERT (Map->Operation =3D=3D MapOperationBusMasterWrite= ); >> =A0=A0=A0=A0=A0 if (Map->Operation !=3D MapOperationBusMasterWrite) { >> @@ -335,10 +468,9 @@ DmaAllocateAlignedBuffer ( >> =A0=A0=A0=A0=A0 return EFI_INVALID_PARAMETER; >> =A0=A0=A0 } >> -=A0 if (MemoryType =3D=3D EfiBootServicesData) { >> -=A0=A0=A0 Allocation =3D AllocateAlignedPages (Pages, Alignment); >> -=A0 } else if (MemoryType =3D=3D EfiRuntimeServicesData) { >> -=A0=A0=A0 Allocation =3D AllocateAlignedRuntimePages (Pages, Alignment)= ; >> +=A0 if (MemoryType =3D=3D EfiBootServicesData || >> +=A0=A0=A0=A0=A0 MemoryType =3D=3D EfiRuntimeServicesData) { >> +=A0=A0=A0 Allocation =3D InternalAllocateAlignedPages (MemoryType, Page= s,=20 >> Alignment); >> =A0=A0=A0 } else { >> =A0=A0=A0=A0=A0 return EFI_INVALID_PARAMETER; >> =A0=A0=A0 } >> @@ -479,6 +611,15 @@ NonCoherentDmaLibConstructor ( >> =A0 { >> =A0=A0=A0 InitializeListHead (&UncachedAllocationList); >> +=A0 // >> +=A0 // Ensure that the combination of DMA addressing offset and limit= =20 >> produces >> +=A0 // a sane value. >> +=A0 // >> +=A0 ASSERT (PcdGet64 (PcdDmaDeviceLimit) > PcdGet64 (PcdDmaDeviceOffset= )); >> + >> +=A0 mDmaHostAddressLimit =3D PcdGet64 (PcdDmaDeviceLimit) - >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0 PcdGet64 (PcdDmaDeviceOffset); >> + >> =A0=A0=A0 // Get the Cpu protocol for later use >> =A0=A0=A0 return gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (V= OID=20 >> **)&mCpu); >> =A0 } >> diff --git=20 >> a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf=20 >> b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf >> index 2db751afee91..1a21cfe4ff23 100644 >> --- a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf >> +++ b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf >> @@ -38,6 +38,7 @@ [Protocols] >> =A0 [Pcd] >> =A0=A0=A0 gEmbeddedTokenSpaceGuid.PcdDmaDeviceOffset >> +=A0 gEmbeddedTokenSpaceGuid.PcdDmaDeviceLimit >> =A0 [Depex] >> =A0=A0=A0 gEfiCpuArchProtocolGuid >> >=20 > For the 82% of the patch I understood: > Reviewed-by: Philippe Mathieu-Daude Leif explained me that "I've reviewed it, but don't fully understand it,=20 but I think it's valuable" translate into a Acked-by on EDK2, so please=20 replace the previous Reviewed-by by: Acked-by: Philippe Mathieu-Daude Thanks, Phil.