apache / nuttx

Apache NuttX is a mature, real-time embedded operating system (RTOS)
https://nuttx.apache.org/
Apache License 2.0
2.76k stars 1.14k forks source link

RISC-V32 MMU Implementation #8602

Open g2gps opened 1 year ago

g2gps commented 1 year ago

We're currently looking at configuring a kernel build for NuttX for using 32 bit risc-v architecture.

I can see that there is a MMU implementation for 64-bit risc-v in arch/risc-v/src/common/riscv_mmu.h.

/* SvX definitions, only Sv39 is currently supported, but it should be
 * trivial to extend the driver to support other SvX implementations
 *
 * Sv39 has:
 * - 4K page size
 * - 3 page table levels
 * - 9-bit VPN width
 */

#ifdef CONFIG_ARCH_MMU_TYPE_SV39
#define RV_MMU_PTE_PADDR_SHIFT  (10)
#define RV_MMU_PTE_PPN_MASK     (((1ul << 44) - 1) << RV_MMU_PTE_PADDR_SHIFT)
#define RV_MMU_PTE_PPN_SHIFT    (2)
#define RV_MMU_VPN_WIDTH        (9)
#define RV_MMU_VPN_MASK         ((1ul << RV_MMU_VPN_WIDTH) - 1)
#define RV_MMU_PT_LEVELS        (3)
#define RV_MMU_VADDR_SHIFT(_n)  (RV_MMU_PAGE_SHIFT + RV_MMU_VPN_WIDTH * \
                                 (RV_MMU_PT_LEVELS - (_n)))
#define RV_MMU_SATP_MODE        (SATP_MODE_SV39)
#define RV_MMU_L1_PAGE_SIZE     (0x40000000) /* 1G */
#define RV_MMU_L2_PAGE_SIZE     (0x200000)   /* 2M */
#define RV_MMU_L3_PAGE_SIZE     (0x1000)     /* 4K */

/* Minimum alignment requirement for any section of memory is 2MB */

#define RV_MMU_SECTION_ALIGN        (RV_MMU_L2_PAGE_SIZE)
#define RV_MMU_SECTION_ALIGN_MASK   (RV_MMU_SECTION_ALIGN - 1)
#else
#error "Unsupported RISC-V MMU implementation selected"
#endif /* CONFIG_ARCH_MMU_TYPE_SV39 */

Is there any guidance or plans for implementing something similar for 32-bit? Or possibly someone has attempted something similar in the past?

xiaoxiang781216 commented 1 year ago

64bit MMU is added by @pussuw. @pussuw could you give some hint?

pussuw commented 1 year ago

The implementation I need is 64-bit only so at least I don't plan to do / will not do anything regarding riscv32.

But it should be pretty easy to extend the implementation for other SvXX types also (including Sv32). I intentionally wrote the driver keeping scalability for other architectures in mind.

In theory you only need to do the above definitions for Sv32 and the implementation "should work". Might be a good idea to check the macros outside of that #ifdef as well. Obviously this has never been tested with Sv32 but I use the Sv39 implementation daily and it works just fine.

When I did the implementation riscv32 and riscv64 had separate implementations, which were merged into one later. So the driver and the public interface might not be 100% compatible with Sv32 as-is.

The most important document obviously is the riscv privileged specification which tells you how the address translations work.

Please do keep in mind that when running riscv in supervisor mode you need some sort of SBI implementation. That implementation is out-of-scope here and you need to choose and integrate it yourself.