Questions about configuring RISC-V MMU

140 views
Skip to first unread message

li bing

unread,
Aug 13, 2023, 11:01:14 PM8/13/23
to RISC-V Firmware Exchange, yon...@intel.com, evan...@intel.com
Hello, everyone
      When we debugged the C920 and set the MMU, we found a problem. The C920 SATP register could not be set normally, and the written and written contents were inconsistent, which made it impossible to call the setting method of edk2/UefiCpuPkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.c.

So I tried to print the result of STAP.

**
  Set SATP mode.

  @param  SatpMode  The SATP mode to be set.

  @retval EFI_INVALID_PARAMETER   The SATP mode was not valid.
  @retval EFI_OUT_OF_RESOURCES    Not enough resource.
  @retval EFI_DEVICE_ERROR        The SATP mode not supported by HW.
  @retval EFI_SUCCESS             The operation succesfully.

**/
STATIC
EFI_STATUS
RiscVMmuSetSatpMode  (
  UINTN  SatpMode
  )
{
  VOID                             *TranslationTable;
  UINTN                            SatpReg;
  UINTN                            Ppn;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemoryMap;
  UINTN                            NumberOfDescriptors;
  UINTN                            Index;
  EFI_STATUS                       Status;

  switch (SatpMode) {
    case SATP_MODE_OFF:
      return EFI_SUCCESS;
    case SATP_MODE_SV39:
      mMaxRootTableLevel = 3;
      mBitPerLevel       = 9;
      mTableEntryCount   = 512;
      break;
    case SATP_MODE_SV48:
      mMaxRootTableLevel = 4;
      mBitPerLevel       = 9;
      mTableEntryCount   = 512;
      break;
    case SATP_MODE_SV57:
      mMaxRootTableLevel = 5;
      mBitPerLevel       = 9;
      mTableEntryCount   = 512;
      break;
    default:
      return EFI_INVALID_PARAMETER;
  }

  // Allocate pages for translation table
  TranslationTable = AllocatePages (1);
  if (TranslationTable == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  ZeroMem (TranslationTable, mTableEntryCount * sizeof (UINTN));

  NumberOfDescriptors = 0;
  MemoryMap           = NULL;
  Status              = gDS->GetMemorySpaceMap (
                               &NumberOfDescriptors,
                               &MemoryMap
                               );
  ASSERT_EFI_ERROR (Status);

  for (Index = 0; Index < NumberOfDescriptors; Index++) {
    if (MemoryMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {
      // Default Read/Write attribute for memory mapped IO
      UpdateRegionMapping (
        MemoryMap[Index].BaseAddress,
        MemoryMap[Index].Length,
        RISCV_PG_R | RISCV_PG_W,
        PTE_ATTRIBUTES_MASK,
        TranslationTable,
        FALSE
        );
    } else if (MemoryMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {
      // Default Read/Write/Execute attribute for system memory
      UpdateRegionMapping (
        MemoryMap[Index].BaseAddress,
        MemoryMap[Index].Length,
        RISCV_PG_R | RISCV_PG_W | RISCV_PG_X,
        PTE_ATTRIBUTES_MASK,
        TranslationTable,
        FALSE
        );
    }
  }

  FreePool ((VOID *)MemoryMap);

  if (GetInterruptState ()) {
    DisableInterrupts ();
  }

  Ppn = (UINTN)TranslationTable >> RISCV_MMU_PAGE_SHIFT;
  ASSERT (!(Ppn & ~(SATP64_PPN)));

  SatpReg  = Ppn;
  SatpReg |= (SatpMode <<
              SATP64_MODE_SHIFT) & SATP64_MODE;

  // The MODE field of the C920 SATP register cannot be read

  DEBUG ((DEBUG_INFO, "SatpReg = %llx\n", SatpReg));
  RiscVSetSupervisorAddressTranslationRegister (SatpReg);
  UINTN  read_SatpReg;
  read_SatpReg = RiscVGetSupervisorAddressTranslationRegister();
  DEBUG ((DEBUG_INFO, "read_SatpReg = %llx\n", read_SatpReg));

  RiscVLocalTlbFlushAll ();

  if (GetInterruptState ()) {
    EnableInterrupts ();
  }

  return Status;
}
The following is the result read,
Found that the high 32-bit register value cannot be read。
Snipaste_2023-08-14_10-52-19.png

So why would it be like this? Please help me analyze it, thank you.

Project repository:
edk2-platform:

Thanks!

Tuan Phan

unread,
Aug 13, 2023, 11:14:46 PM8/13/23
to li bing, RISC-V Firmware Exchange, evan...@intel.com, yon...@intel.com
The code tries to set satp from max mode. If it can’t set mode then will lower mode and try again.

So if you set satp mode = 9 and it failed to write then your HW doesn’t support that mode.

--
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/bb2fd803-3ea9-4b58-8fec-652cfad39bf9n%40riscv.org.

li bing

unread,
Aug 14, 2023, 2:37:31 AM8/14/23
to RISC-V Firmware Exchange, tp...@ventanamicro.com, RISC-V Firmware Exchange, evan...@intel.com, yon...@intel.com, li bing

Thank you for your answer  tphan,

I'm sorry, I didn't describe my problem clearly. We changed some of the content for this problem, and did not use automatic filtering to set it up, but forced it to set it up.
Therefore, we copied BaseRiscVMmuLib and changed the content in the directory.
The copied and changed address is under the warehouse:
edk2-platforms/Platform/Sophgo/SG2042Pkg/Library/RiscVMmuLib/RiscVMmuLib.c
The content is:

/**
  The API to configure and enable RISC-V MMU with the highest mode supported.

  @retval EFI_OUT_OF_RESOURCES    Not enough resource.
  @retval EFI_SUCCESS             The operation succesfully.

**/
EFI_STATUS
EFIAPI
RiscVConfigureMmu (
  VOID
  )
{
  EFI_STATUS  Status;

  /* Setup C920 MMU with SATP mode svxx*/
  Status = RiscVMmuSetSatpMode (SATP_MODE_SV57);
  ASSERT (!EFI_ERROR (Status));

Sorry, no changes were made to the output printing, so it keeps outputting as sv48.

  DEBUG ((
    DEBUG_INFO,
    "%a: SATP mode %d successfully configured\n",
    __func__,
    SATP_MODE_SV48
  ));

  return Status;
}

In this way, we forcefully set the mode of SATP,
Try to set the three modes of SV57, SV48, and SV39, but find that only SV57, SV48 can be executed and enter the os. And SV39 cannot continue to execute.
sv57.png
sv48.png
sv39.png
We queried the relevant technical manual, the following is the setting method of SATP
STAP.png
So I'm not quite sure what could be causing this, memory mapping or something else???

Thanks!

li bing

unread,
Aug 14, 2023, 3:05:50 AM8/14/23
to RISC-V Firmware Exchange, li bing, tp...@ventanamicro.com, RISC-V Firmware Exchange, evan...@intel.com, yon...@intel.com
By Tuan Phan <tp...@ventanamicro.com> answer:

If you modified the code, from what I can tell is your change doesn’t detect if satp mode set is successfully or not.

In your case, SV57, SV48 is falling but you still let it continue then the actual satp mode is still bare mode and no MMU is enabled. So the code is doing as same as before without MMU.

In the case SV39, set satp mode successfully, MMU enabled. But it is getting fault exception due to the following reason

- The memory range has not been added to GCD. In other words, no memory hob is set up during HOB phase.

OR

- The IO range has not been added to GCD, in this case it is your UART. If you look at the OvmfPkg/RiscVVirt/Sec/Platform.c, the PopulateIoResources (Base, "ns16550a") line is used to add UART range to GCD for DXE phase. You need to do the same thing for all IOs that you will access. Normally DXE driver will add IO range to GCD using EDk2 API, but UART normally accessed directly.


Because of my mistake, I replied to the question, but Tuan Phan still answered it, so I will synchronize the results.
Thanks ,  Tuan Phan.
Thanks ,   everyone.

yuqing...@gmail.com

unread,
Aug 15, 2023, 11:15:36 PM8/15/23
to RISC-V Firmware Exchange, RISC-V Firmware Exchange
Hi everyone,
After MMU is enabled, I get store access fault (not page fault) when executing AMO instructions (AMOADD.W) in SG2042 (Xuantie C920). But replacing AMOADD.W with regular ADD instruction fixes access fault problem.

../MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c:2861
微信图片_20230816110307.png
../MdePkg/Library/BaseSynchronizationLib/Synchronization.S:63
屏幕截图 2023-08-16 104956.png

屏幕截图 2023-08-16 110604.png

So why would it be like this? Some Special initailization is needed to make AMO instructionas functional?

Thanks!

Tuan Phan

unread,
Aug 16, 2023, 12:35:55 AM8/16/23
to yuqing...@gmail.com, RISC-V Firmware Exchange, RISC-V Firmware Exchange

You need to check whether AMOArithmetic PMA enabled for the failing region(0x7FFFF3D10). Refer to section 3.6.3 in riscv-privileged

 

From: yuqing...@gmail.com <yuqing...@gmail.com>
Date: Tuesday, August 15, 2023 at 8:15 PM
To: RISC-V Firmware Exchange <fw-ex...@riscv.org>
Cc: RISC-V Firmware Exchange <fw-ex...@riscv.org>
Subject: Re: Questions about configuring RISC-V MMU

Hi everyone,

After MMU is enabled, I get store access fault (not page fault) when executing AMO instructions (AMOADD.W) in SG2042 (Xuantie C920). But replacing AMOADD.W with regular ADD instruction fixes access fault problem.

 

../MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c:2861

../MdePkg/Library/BaseSynchronizationLib/Synchronization.S:63

 

We queried the relevant technical manual, the following is the setting method of SATP

 

So why would it be like this? Please help me analyze it, thank you.

 

Project repository:

edk2-platform:

 

Thanks!

--
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/bb2fd803-3ea9-4b58-8fec-652cfad39bf9n%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.

Reply all
Reply to author
Forward
0 new messages