


--
You received this message because you are subscribed to the Google Groups "RISC-V Firmware Exchange" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fw-exchange...@riscv.org.
To view this discussion on the web visit https://groups.google.com/a/riscv.org/d/msgid/fw-exchange/32c53659-c980-4af0-a361-ce05b00228e3n%40riscv.org.
Hi,
In Sec/SecMain.c:, search for HobConstructor then define UefiMemoryBase < 4GB
Create a DXE driver then register on ready to boot event:
VOID
EFIAPI
OnReadyToBootServices (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINTN MemoryMapSize;
EFI_MEMORY_DESCRIPTOR *MemoryMap, *Desc;
UINTN MapKey;
UINTN DescriptorSize;
UINT32 DescriptorVersion;
EFI_PHYSICAL_ADDRESS Addr;
UINTN Idx;
UINTN Pages;
//
// Close the event, so it will not be signalled again.
//
gBS->CloseEvent (Event);
MemoryMap = NULL;
MemoryMapSize = 0;
Pages = 0;
Status = gBS->GetMemoryMap (
&MemoryMapSize,
MemoryMap,
&MapKey,
&DescriptorSize,
&DescriptorVersion
);
if (Status == EFI_BUFFER_TOO_SMALL) {
Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
MemoryMap = AllocatePages (Pages);
//
// Get System MemoryMap
//
Status = gBS->GetMemoryMap (
&MemoryMapSize,
MemoryMap,
&MapKey,
&DescriptorSize,
&DescriptorVersion
);
}
if (EFI_ERROR (Status) || MemoryMap == NULL) {
DEBUG ((DEBUG_ERROR, "%a: Failed to get memory map\n", __FUNCTION__));
if (MemoryMap) {
FreePages ((VOID *)MemoryMap, Pages);
}
return;
}
Desc = MemoryMap;
for (Idx = 0; Idx < (MemoryMapSize / DescriptorSize); Idx++) {
if (Desc->Type == EfiConventionalMemory &&
((Desc->PhysicalStart > MAX_UINT32) || (Desc->PhysicalStart + Desc->NumberOfPages * EFI_PAGE_SIZE) > MAX_UINT32)) {
if (Desc->PhysicalStart > MAX_UINT32) {
Addr = Desc->PhysicalStart;
Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesData, Desc->NumberOfPages, &Addr);
} else {
Addr = 0x100000000ULL;
Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesData, Desc->NumberOfPages - EFI_SIZE_TO_PAGES (0x100000000 - Desc->PhysicalStart), &Addr);
}
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Failed to allocate boot service data at %llX\n", __FUNCTION__, Addr));
}
}
Desc = (EFI_MEMORY_DESCRIPTOR *)((UINT64)Desc + DescriptorSize);
}
FreePages ((VOID *)MemoryMap, Pages);
}
If a driver allocate memory above 4GB before ReadToBoot event, you can let above code run before that point.
From:
John Chew <yuinye...@starfivetech.com>
Date: Tuesday, August 8, 2023 at 10:44 PM
To: RISC-V Firmware Exchange <fw-ex...@riscv.org>
Cc: tp...@ventanamicro.com <tp...@ventanamicro.com>, RISC-V Firmware Exchange <fw-ex...@riscv.org>, yon...@intel.com <yon...@intel.com>, John Chew <yuinye...@starfivetech.com>
Subject: Re: How to dispatch DXE in 32-bit address in PEI-less flow ?
Hi Tuan,
"define UEFI top memory in 32bits range"
I notice that PCD "gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable" is able to limit the top address (please correct me if I'm wrong).
But I meet some issues using this PCD.
Before I proceed further with the investigation, is this PCD suitable to implement what you have suggested or there is another method to do it?
by any chance, do you know any example implementation that I can use for reference?
Thanks
Regards,
John
On Thursday, August 3, 2023 at 2:26:03 PM UTC+8 tp...@ventanamicro.com wrote:
You can define UEFI top memory in 32bits range then build memory hob description as bootloader data for all above 4GB. So uefi never uses 64bits and Linux can reclaim all memory.
On Wed, Aug 2, 2023 at 11:17 PM John Chew <yuinye...@starfivetech.com> wrote:
Hi everyone,
In PEI-less flow, RAM region is allocated based on the "memory" node.
../OvmfPkg/RiscVVirt/Sec/Memory.c:299
In the device tree, the memory node is set as 0x4100_0000 ~ 0x1_0000_0000:
During DXE dispatching, it will dispatch the packages in 64-bit addresses.
VF2's JH7110 MMC driver DMA can only work with 32-bit addressing.
Thus, dispatching the driver in a 64-bit address causes the DMA to fail..
The current workaround is to set the memory node to 0x4100_0000 ~ 0x3F00_0000:
https://github.com/johnchewyy/edk2-platforms/commit/aee7012740f9adaaa972d6ade22ccb86cb72c413
Since Linux is using the same DTB as UEFI, reducing the memory range will cause errors in Linux.
I'm curious if there is a way to restrict the UEFI's RAM allocation to only utilize a 32-bit address range.
Alternatively, is there a method to enforce the use of PCD for assigning the RAM range?
Project repository:
edk2: https://github.com/johnchewyy/edk2/tree/vf2_jh7110_devel_peiless_multiarch
edk2-platform: https://github.com/johnchewyy/edk2-platforms/tree/vf2_jh7110_devel_peiless_multiarch
Log attachment:
dma_okay.txt - memory node: 0x4100_0000 ~ 0x3F00_0000
dma_hang.txt - memory node: 0x4100_0000 ~ 0x1_0000_0000
Thanks!
Regards,
John



To view this discussion on the web visit https://groups.google.com/a/riscv.org/d/msgid/fw-exchange/18de742e-2d73-40ae-8489-f14a2e4742f8n%40riscv.org.



Hi John,
Without looking your source code, not sure what I can tell. If you can control your MMC driver then just use EDK2 API to allocate page within 4GB. It is what PCI driver does when deal with device not support above 4GB memory
if (!RootBridge->DmaAbove4G ||
((Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0))
{
//
// Limit allocations to memory below 4GB
//
AllocateType = AllocateMaxAddress;
PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(SIZE_4GB - 1);
}
Status = gBS->AllocatePages (
AllocateType,
MemoryType,
Pages,
&PhysicalAddress
);
From:
John Chew <yuinye...@starfivetech.com>
Date: Friday, August 18, 2023 at 1:58 AM
To: RISC-V Firmware Exchange <fw-ex...@riscv.org>
Cc: John Chew <yuinye...@starfivetech.com>, tp...@ventanamicro.com <tp...@ventanamicro.com>, RISC-V Firmware Exchange <fw-ex...@riscv.org>, yon...@intel.com <yon...@intel.com>
Subject: Re: How to dispatch DXE in 32-bit address in PEI-less flow ?
Hi Tuan,
I notice when my low address of RAM is set to 0x40000000 will cause my "EfiBootServiceData" to allocate to a 64-bit address.
This is the snippet of my print code:

Based on the log below, you can see that:
Lower RAM adrdess: 0x4000_0000 -> DMA buffer: 0x1_3F22_A000
Lower RAM address: 0x4100_0000 -> DMA buffer: 0xFFFF_F000
Also based on the log, I found out that after the new "EfiBootServiceData" page is allocated, the new page's physical start address is located at 0xFFFF_F000

I'm not sure if the "reserve" memory has anything to do with this error:

I have also included the log for both tests log in the attachment.
Thank you =)
Regards,
John
On Monday, August 14, 2023 at 4:58:29 PM UTC+8 John Chew wrote:
Hi Tuan,
"need to do the code that i showed you before the failing point "
It works!!
Thank you for your support =)
Regards,
John
On Friday, August 11, 2023 at 12:36:33 PM UTC+8 tp...@ventanamicro.com wrote:
As i said, you need to do the code that i showed you before the failing point
On Thu, Aug 10, 2023 at 8:47 PM John Chew <yuinye...@starfivetech.com> wrote:
Hi Tuan,
Thanks for the code example. I tried your suggestion:
" In Sec/SecMain.c:, search for HobConstructor then define UefiMemoryBase < 4GB"
I found out that the allocated page for "EfiBootServiceData" is still in 64-bit range.
Below is the memory I printed the memory for your reference.
Thanks again!
Regards,
John
In the device tree, the memory node is set as 0x4100_0000 ~ 0x1_0000_0000:
During DXE dispatching, it will dispatch the packages in 64-bit addresses.
VF2's JH7110 MMC driver DMA can only work with 32-bit addressing.
Thus, dispatching the driver in a 64-bit address causes the DMA to fail..
The current workaround is to set the memory node to 0x4100_0000 ~ 0x3F00_0000:
https://github.com/johnchewyy/edk2-platforms/commit/aee7012740f9adaaa972d6ade22ccb86cb72c413
Since Linux is using the same DTB as UEFI, reducing the memory range will cause errors in Linux.
I'm curious if there is a way to restrict the UEFI's RAM allocation to only utilize a 32-bit address range.
Alternatively, is there a method to enforce the use of PCD for assigning the RAM range?
Project repository:
edk2: https://github.com/johnchewyy/edk2/tree/vf2_jh7110_devel_peiless_multiarch
edk2-platform: https://github.com/johnchewyy/edk2-platforms/tree/vf2_jh7110_devel_peiless_multiarch
Log attachment:
dma_okay.txt - memory node: 0x4100_0000 ~ 0x3F00_0000
dma_hang.txt - memory node: 0x4100_0000 ~ 0x1_0000_0000
Thanks!
Regards,
John
--
You received this message because you are subscribed to the Google Groups "RISC-V Firmware Exchange" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fw-exchange...@riscv.org.
To view this discussion on the web visit https://groups.google.com/a/riscv.org/d/msgid/fw-exchange/32c53659-c980-4af0-a361-ce05b00228e3n%40riscv.org.
--
You received this message because you are subscribed to the Google Groups "RISC-V Firmware Exchange" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fw-exchange...@riscv.org.