risc-v: SV32 MMU support for qemu-rv.
This commit is contained in:
parent
536739d2da
commit
01b0305ab5
@ -166,6 +166,7 @@ config ARCH_CHIP_QEMU_RV
|
|||||||
select ARCH_HAVE_MPU
|
select ARCH_HAVE_MPU
|
||||||
select ARCH_HAVE_MMU
|
select ARCH_HAVE_MMU
|
||||||
select ARCH_MMU_TYPE_SV39 if ARCH_CHIP_QEMU_RV64
|
select ARCH_MMU_TYPE_SV39 if ARCH_CHIP_QEMU_RV64
|
||||||
|
select ARCH_MMU_TYPE_SV32 if ARCH_CHIP_QEMU_RV32
|
||||||
select ARCH_HAVE_ADDRENV
|
select ARCH_HAVE_ADDRENV
|
||||||
select ARCH_NEED_ADDRENV_MAPPING
|
select ARCH_NEED_ADDRENV_MAPPING
|
||||||
select ARCH_HAVE_S_MODE
|
select ARCH_HAVE_S_MODE
|
||||||
@ -255,6 +256,10 @@ config ARCH_MMU_TYPE_SV39
|
|||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config ARCH_MMU_TYPE_SV32
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
config ARCH_HAVE_S_MODE
|
config ARCH_HAVE_S_MODE
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
@ -44,6 +44,8 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_ARCH_MMU_TYPE_SV39
|
#ifdef CONFIG_ARCH_MMU_TYPE_SV39
|
||||||
# define ARCH_PGT_MAX_LEVELS (3)
|
# define ARCH_PGT_MAX_LEVELS (3)
|
||||||
|
#elif CONFIG_ARCH_MMU_TYPE_SV32
|
||||||
|
# define ARCH_PGT_MAX_LEVELS (2)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Amount of static page tables allocated for an address environment */
|
/* Amount of static page tables allocated for an address environment */
|
||||||
|
@ -48,6 +48,11 @@ static const size_t g_pgt_sizes[] =
|
|||||||
{
|
{
|
||||||
RV_MMU_L1_PAGE_SIZE, RV_MMU_L2_PAGE_SIZE, RV_MMU_L3_PAGE_SIZE
|
RV_MMU_L1_PAGE_SIZE, RV_MMU_L2_PAGE_SIZE, RV_MMU_L3_PAGE_SIZE
|
||||||
};
|
};
|
||||||
|
#elif CONFIG_ARCH_MMU_TYPE_SV32
|
||||||
|
static const size_t g_pgt_sizes[] =
|
||||||
|
{
|
||||||
|
RV_MMU_L1_PAGE_SIZE, RV_MMU_L2_PAGE_SIZE
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -31,27 +31,6 @@
|
|||||||
|
|
||||||
#define RV_MMU_PAGE_ENTRIES (RV_MMU_PAGE_SIZE / sizeof(uintptr_t))
|
#define RV_MMU_PAGE_ENTRIES (RV_MMU_PAGE_SIZE / sizeof(uintptr_t))
|
||||||
|
|
||||||
/* Supervisor Address Translation and Protection (satp) */
|
|
||||||
|
|
||||||
#define SATP_PPN_SHIFT (0)
|
|
||||||
#define SATP_PPN_MASK (((1ul << 44) - 1) << SATP_PPN_SHIFT)
|
|
||||||
#define SATP_ASID_SHIFT (44)
|
|
||||||
#define SATP_ASID_MASK (((1ul << 16) - 1) << SATP_ASID_SHIFT)
|
|
||||||
#define SATP_MODE_SHIFT (60)
|
|
||||||
#define SATP_MODE_MASK (((1ul << 4) - 1) << SATP_MODE_SHIFT)
|
|
||||||
|
|
||||||
/* Modes, for RV32 only 1 is valid, for RV64 1-7 and 10-15 are reserved */
|
|
||||||
|
|
||||||
#define SATP_MODE_BARE (0ul)
|
|
||||||
#define SATP_MODE_SV32 (1ul)
|
|
||||||
#define SATP_MODE_SV39 (8ul)
|
|
||||||
#define SATP_MODE_SV48 (9ul)
|
|
||||||
|
|
||||||
/* satp address to PPN translation */
|
|
||||||
|
|
||||||
#define SATP_ADDR_TO_PPN(_addr) ((_addr) >> RV_MMU_PAGE_SHIFT)
|
|
||||||
#define SATP_PPN_TO_ADDR(_ppn) ((_ppn) << RV_MMU_PAGE_SHIFT)
|
|
||||||
|
|
||||||
/* Common Page Table Entry (PTE) bits */
|
/* Common Page Table Entry (PTE) bits */
|
||||||
|
|
||||||
#define PTE_VALID (1 << 0) /* PTE is valid */
|
#define PTE_VALID (1 << 0) /* PTE is valid */
|
||||||
@ -85,24 +64,32 @@
|
|||||||
#define MMU_KTEXT_FLAGS (PTE_R | PTE_X | PTE_G)
|
#define MMU_KTEXT_FLAGS (PTE_R | PTE_X | PTE_G)
|
||||||
#define MMU_KDATA_FLAGS (PTE_R | PTE_W | PTE_G)
|
#define MMU_KDATA_FLAGS (PTE_R | PTE_W | PTE_G)
|
||||||
|
|
||||||
/* SvX definitions, only Sv39 is currently supported, but it should be
|
/* Modes, for RV32 only 1 is valid, for RV64 1-7 and 10-15 are reserved */
|
||||||
* trivial to extend the driver to support other SvX implementations
|
|
||||||
*
|
#define SATP_MODE_BARE (0ul)
|
||||||
* Sv39 has:
|
#define SATP_MODE_SV32 (1ul)
|
||||||
|
#define SATP_MODE_SV39 (8ul)
|
||||||
|
#define SATP_MODE_SV48 (9ul)
|
||||||
|
|
||||||
|
#if CONFIG_ARCH_HAVE_MMU
|
||||||
|
#define RV_MMU_PTE_PADDR_SHIFT (10)
|
||||||
|
#define RV_MMU_PTE_PPN_SHIFT (2)
|
||||||
|
#define RV_MMU_VADDR_SHIFT(_n) (RV_MMU_PAGE_SHIFT + RV_MMU_VPN_WIDTH * \
|
||||||
|
(RV_MMU_PT_LEVELS - (_n)))
|
||||||
|
/* Sv39 has:
|
||||||
* - 4K page size
|
* - 4K page size
|
||||||
* - 3 page table levels
|
* - 3 page table levels
|
||||||
* - 9-bit VPN width
|
* - 9-bit VPN width
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_MMU_TYPE_SV39
|
#ifdef CONFIG_ARCH_MMU_TYPE_SV39
|
||||||
#define RV_MMU_PTE_PADDR_SHIFT (10)
|
#define RV_MMU_PPN_WIDTH 44
|
||||||
#define RV_MMU_PTE_PPN_MASK (((1ul << 44) - 1) << RV_MMU_PTE_PADDR_SHIFT)
|
#define RV_MMU_ASID_WIDTH 16
|
||||||
#define RV_MMU_PTE_PPN_SHIFT (2)
|
#define RV_MMU_MODE_WIDTH 4
|
||||||
|
#define RV_MMU_PTE_PPN_MASK (((1ul << RV_MMU_PPN_WIDTH) - 1) << RV_MMU_PTE_PADDR_SHIFT)
|
||||||
#define RV_MMU_VPN_WIDTH (9)
|
#define RV_MMU_VPN_WIDTH (9)
|
||||||
#define RV_MMU_VPN_MASK ((1ul << RV_MMU_VPN_WIDTH) - 1)
|
#define RV_MMU_VPN_MASK ((1ul << RV_MMU_VPN_WIDTH) - 1)
|
||||||
#define RV_MMU_PT_LEVELS (3)
|
#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_SATP_MODE (SATP_MODE_SV39)
|
||||||
#define RV_MMU_L1_PAGE_SIZE (0x40000000) /* 1G */
|
#define RV_MMU_L1_PAGE_SIZE (0x40000000) /* 1G */
|
||||||
#define RV_MMU_L2_PAGE_SIZE (0x200000) /* 2M */
|
#define RV_MMU_L2_PAGE_SIZE (0x200000) /* 2M */
|
||||||
@ -112,9 +99,46 @@
|
|||||||
|
|
||||||
#define RV_MMU_SECTION_ALIGN (RV_MMU_L2_PAGE_SIZE)
|
#define RV_MMU_SECTION_ALIGN (RV_MMU_L2_PAGE_SIZE)
|
||||||
#define RV_MMU_SECTION_ALIGN_MASK (RV_MMU_SECTION_ALIGN - 1)
|
#define RV_MMU_SECTION_ALIGN_MASK (RV_MMU_SECTION_ALIGN - 1)
|
||||||
|
|
||||||
|
/* Sv32 has:
|
||||||
|
* - 4K page size
|
||||||
|
* - 2 page table levels
|
||||||
|
* - 10-bit VPN width
|
||||||
|
*/
|
||||||
|
|
||||||
|
#elif CONFIG_ARCH_MMU_TYPE_SV32
|
||||||
|
#define RV_MMU_PPN_WIDTH 22
|
||||||
|
#define RV_MMU_ASID_WIDTH 9
|
||||||
|
#define RV_MMU_MODE_WIDTH 1
|
||||||
|
#define RV_MMU_PTE_PPN_MASK (((1ul << RV_MMU_PPN_WIDTH) - 1) << RV_MMU_PTE_PADDR_SHIFT)
|
||||||
|
#define RV_MMU_VPN_WIDTH (10)
|
||||||
|
#define RV_MMU_VPN_MASK ((1ul << RV_MMU_VPN_WIDTH) - 1)
|
||||||
|
#define RV_MMU_PT_LEVELS (2)
|
||||||
|
#define RV_MMU_SATP_MODE (SATP_MODE_SV32)
|
||||||
|
#define RV_MMU_L1_PAGE_SIZE (0x400000) /* 4M */
|
||||||
|
#define RV_MMU_L2_PAGE_SIZE (0x1000) /* 4K */
|
||||||
|
|
||||||
|
#define RV_MMU_SECTION_ALIGN (RV_MMU_L1_PAGE_SIZE)
|
||||||
|
#define RV_MMU_SECTION_ALIGN_MASK (RV_MMU_SECTION_ALIGN - 1)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Unsupported RISC-V MMU implementation selected"
|
#error "Unsupported RISC-V MMU implementation selected"
|
||||||
#endif /* CONFIG_ARCH_MMU_TYPE_SV39 */
|
#endif
|
||||||
|
#endif /* CONFIG_ARCH_HAVE_MMU */
|
||||||
|
|
||||||
|
/* Supervisor Address Translation and Protection (satp) */
|
||||||
|
|
||||||
|
#define SATP_PPN_SHIFT (0)
|
||||||
|
#define SATP_PPN_MASK (((1ul << RV_MMU_PPN_WIDTH) - 1) << SATP_PPN_SHIFT)
|
||||||
|
#define SATP_ASID_SHIFT (RV_MMU_PPN_WIDTH)
|
||||||
|
#define SATP_ASID_MASK (((1ul << RV_MMU_ASID_WIDTH) - 1) << SATP_ASID_SHIFT)
|
||||||
|
#define SATP_MODE_SHIFT (RV_MMU_PPN_WIDTH + RV_MMU_ASID_WIDTH)
|
||||||
|
#define SATP_MODE_MASK (((1ul << RV_MMU_MODE_WIDTH) - 1) << SATP_MODE_SHIFT)
|
||||||
|
|
||||||
|
/* satp address to PPN translation */
|
||||||
|
|
||||||
|
#define SATP_ADDR_TO_PPN(_addr) ((_addr) >> RV_MMU_PAGE_SHIFT)
|
||||||
|
#define SATP_PPN_TO_ADDR(_ppn) ((_ppn) << RV_MMU_PAGE_SHIFT)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
|
@ -45,6 +45,28 @@
|
|||||||
#define MMU_IO_BASE (0x00000000)
|
#define MMU_IO_BASE (0x00000000)
|
||||||
#define MMU_IO_SIZE (0x80000000)
|
#define MMU_IO_SIZE (0x80000000)
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_MMU_TYPE_SV32
|
||||||
|
|
||||||
|
/* Physical and virtual addresses to page tables (vaddr = paddr mapping) */
|
||||||
|
|
||||||
|
#define PGT_L1_PBASE (uintptr_t)&m_l1_pgtable
|
||||||
|
#define PGT_L2_PBASE (uintptr_t)&m_l2_pgtable
|
||||||
|
#define PGT_L1_VBASE PGT_L1_PBASE
|
||||||
|
#define PGT_L2_VBASE PGT_L2_PBASE
|
||||||
|
|
||||||
|
#define PGT_L1_SIZE (1024) /* Enough to map 4 GiB */
|
||||||
|
#define PGT_L2_SIZE (3072) /* Enough to map 12 MiB */
|
||||||
|
|
||||||
|
#define SLAB_COUNT (sizeof(m_l2_pgtable) / RV_MMU_PAGE_SIZE)
|
||||||
|
|
||||||
|
#define KMM_PAGE_SIZE RV_MMU_L2_PAGE_SIZE
|
||||||
|
#define KMM_PBASE PGT_L2_PBASE
|
||||||
|
#define KMM_PBASE_IDX 2
|
||||||
|
#define KMM_SPBASE PGT_L1_PBASE
|
||||||
|
#define KMM_SPBASE_IDX 1
|
||||||
|
|
||||||
|
#elif CONFIG_ARCH_MMU_TYPE_SV39
|
||||||
|
|
||||||
/* Physical and virtual addresses to page tables (vaddr = paddr mapping) */
|
/* Physical and virtual addresses to page tables (vaddr = paddr mapping) */
|
||||||
|
|
||||||
#define PGT_L1_PBASE (uintptr_t)&m_l1_pgtable
|
#define PGT_L1_PBASE (uintptr_t)&m_l1_pgtable
|
||||||
@ -60,6 +82,16 @@
|
|||||||
|
|
||||||
#define SLAB_COUNT (sizeof(m_l3_pgtable) / RV_MMU_PAGE_SIZE)
|
#define SLAB_COUNT (sizeof(m_l3_pgtable) / RV_MMU_PAGE_SIZE)
|
||||||
|
|
||||||
|
#define KMM_PAGE_SIZE RV_MMU_L3_PAGE_SIZE
|
||||||
|
#define KMM_PBASE PGT_L3_PBASE
|
||||||
|
#define KMM_PBASE_IDX 3
|
||||||
|
#define KMM_SPBASE PGT_L2_PBASE
|
||||||
|
#define KMM_SPBASE_IDX 2
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error No valid MMU defined.
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -77,9 +109,11 @@ typedef struct pgalloc_slab_s pgalloc_slab_t;
|
|||||||
|
|
||||||
/* Kernel mappings simply here, mapping is vaddr=paddr */
|
/* Kernel mappings simply here, mapping is vaddr=paddr */
|
||||||
|
|
||||||
static uint64_t m_l1_pgtable[PGT_L1_SIZE] locate_data(".pgtables");
|
static size_t m_l1_pgtable[PGT_L1_SIZE] locate_data(".pgtables");
|
||||||
static uint64_t m_l2_pgtable[PGT_L2_SIZE] locate_data(".pgtables");
|
static size_t m_l2_pgtable[PGT_L2_SIZE] locate_data(".pgtables");
|
||||||
static uint64_t m_l3_pgtable[PGT_L3_SIZE] locate_data(".pgtables");
|
#ifdef CONFIG_ARCH_MMU_TYPE_SV39
|
||||||
|
static size_t m_l3_pgtable[PGT_L3_SIZE] locate_data(".pgtables");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Kernel mappings (L1 base) */
|
/* Kernel mappings (L1 base) */
|
||||||
|
|
||||||
@ -99,10 +133,12 @@ static pgalloc_slab_t g_slabs[SLAB_COUNT];
|
|||||||
* Name: slab_init
|
* Name: slab_init
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Initialize slab allocator for L3 page table entries
|
* Initialize slab allocator for L2 or L3 page table entries
|
||||||
|
*
|
||||||
|
* L2 Page table is used for SV32. L3 used for SV39
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* start - Beginning of the L3 page table pool
|
* start - Beginning of the L2 or L3 page table pool
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
@ -124,7 +160,9 @@ static void slab_init(uintptr_t start)
|
|||||||
* Name: slab_alloc
|
* Name: slab_alloc
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate single slab for L3 page table entry
|
* Allocate single slab for L2/L3 page table entry
|
||||||
|
*
|
||||||
|
* L2 Page table is used for SV32. L3 used for SV39
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
@ -152,7 +190,7 @@ static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
|
|||||||
uint32_t mmuflags)
|
uint32_t mmuflags)
|
||||||
{
|
{
|
||||||
uintptr_t endaddr;
|
uintptr_t endaddr;
|
||||||
uintptr_t l3pbase;
|
uintptr_t pbase;
|
||||||
int npages;
|
int npages;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
@ -164,28 +202,30 @@ static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
|
|||||||
|
|
||||||
for (i = 0; i < npages; i += RV_MMU_PAGE_ENTRIES)
|
for (i = 0; i < npages; i += RV_MMU_PAGE_ENTRIES)
|
||||||
{
|
{
|
||||||
/* See if a L3 mapping exists ? */
|
/* See if a mapping exists ? */
|
||||||
|
|
||||||
l3pbase = mmu_pte_to_paddr(mmu_ln_getentry(2, PGT_L2_VBASE, vaddr));
|
pbase = mmu_pte_to_paddr(mmu_ln_getentry(
|
||||||
if (!l3pbase)
|
KMM_SPBASE_IDX, KMM_SPBASE, vaddr));
|
||||||
|
if (!pbase)
|
||||||
{
|
{
|
||||||
/* No, allocate 1 page, this must not fail */
|
/* No, allocate 1 page, this must not fail */
|
||||||
|
|
||||||
l3pbase = slab_alloc();
|
pbase = slab_alloc();
|
||||||
DEBUGASSERT(l3pbase);
|
DEBUGASSERT(pbase);
|
||||||
|
|
||||||
/* Map it to the L3 table */
|
/* Map it to the new table */
|
||||||
|
|
||||||
mmu_ln_setentry(2, PGT_L2_VBASE, l3pbase, vaddr, MMU_UPGT_FLAGS);
|
mmu_ln_setentry(
|
||||||
|
KMM_SPBASE_IDX, KMM_SPBASE, pbase, vaddr, MMU_UPGT_FLAGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then add the L3 mappings */
|
/* Then add the mappings */
|
||||||
|
|
||||||
for (j = 0; j < RV_MMU_PAGE_ENTRIES && vaddr < endaddr; j++)
|
for (j = 0; j < RV_MMU_PAGE_ENTRIES && vaddr < endaddr; j++)
|
||||||
{
|
{
|
||||||
mmu_ln_setentry(3, l3pbase, paddr, vaddr, mmuflags);
|
mmu_ln_setentry(KMM_PBASE_IDX, pbase, paddr, vaddr, mmuflags);
|
||||||
paddr += RV_MMU_L3_PAGE_SIZE;
|
paddr += KMM_PAGE_SIZE;
|
||||||
vaddr += RV_MMU_L3_PAGE_SIZE;
|
vaddr += KMM_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,16 +238,16 @@ static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
|
|||||||
* Name: qemu_rv_kernel_mappings
|
* Name: qemu_rv_kernel_mappings
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Setup kernel mappings when usinc CONFIG_BUILD_KERNEL. Sets up the kernel
|
* Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up the kernel
|
||||||
* MMU mappings.
|
* MMU mappings.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void qemu_rv_kernel_mappings(void)
|
void qemu_rv_kernel_mappings(void)
|
||||||
{
|
{
|
||||||
/* Initialize slab allocator for L3 page tables */
|
/* Initialize slab allocator for the L2/L3 page tables */
|
||||||
|
|
||||||
slab_init(PGT_L3_PBASE);
|
slab_init(KMM_PBASE);
|
||||||
|
|
||||||
/* Begin mapping memory to MMU; note that at this point the MMU is not yet
|
/* Begin mapping memory to MMU; note that at this point the MMU is not yet
|
||||||
* active, so the page table virtual addresses are actually physical
|
* active, so the page table virtual addresses are actually physical
|
||||||
@ -215,7 +255,7 @@ void qemu_rv_kernel_mappings(void)
|
|||||||
* this mapping is quite simple to do
|
* this mapping is quite simple to do
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Map I/O region, use 2 L1 entries (i.e. 2 * 1GB address space) */
|
/* Map I/O region, use enough large page tables for the IO region. */
|
||||||
|
|
||||||
binfo("map I/O regions\n");
|
binfo("map I/O regions\n");
|
||||||
mmu_ln_map_region(1, PGT_L1_VBASE, MMU_IO_BASE, MMU_IO_BASE,
|
mmu_ln_map_region(1, PGT_L1_VBASE, MMU_IO_BASE, MMU_IO_BASE,
|
||||||
@ -229,6 +269,8 @@ void qemu_rv_kernel_mappings(void)
|
|||||||
binfo("map kernel data\n");
|
binfo("map kernel data\n");
|
||||||
map_region(KSRAM_START, KSRAM_START, KSRAM_SIZE, MMU_KDATA_FLAGS);
|
map_region(KSRAM_START, KSRAM_START, KSRAM_SIZE, MMU_KDATA_FLAGS);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_MMU_TYPE_SV39
|
||||||
|
|
||||||
/* Connect the L1 and L2 page tables for the kernel text and data */
|
/* Connect the L1 and L2 page tables for the kernel text and data */
|
||||||
|
|
||||||
binfo("connect the L1 and L2 page tables\n");
|
binfo("connect the L1 and L2 page tables\n");
|
||||||
@ -239,6 +281,10 @@ void qemu_rv_kernel_mappings(void)
|
|||||||
binfo("map the page pool\n");
|
binfo("map the page pool\n");
|
||||||
mmu_ln_map_region(2, PGT_L2_VBASE, PGPOOL_START, PGPOOL_START, PGPOOL_SIZE,
|
mmu_ln_map_region(2, PGT_L2_VBASE, PGPOOL_START, PGPOOL_START, PGPOOL_SIZE,
|
||||||
MMU_KDATA_FLAGS);
|
MMU_KDATA_FLAGS);
|
||||||
|
#elif CONFIG_ARCH_MMU_TYPE_SV32
|
||||||
|
binfo("map the page pool\n");
|
||||||
|
map_region(PGPOOL_START, PGPOOL_START, PGPOOL_SIZE, MMU_KDATA_FLAGS);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -258,6 +304,6 @@ void qemu_rv_mm_init(void)
|
|||||||
|
|
||||||
/* Enable MMU (note: system is still in M-mode) */
|
/* Enable MMU (note: system is still in M-mode) */
|
||||||
|
|
||||||
binfo("mmu_enable: satp=%lx\n", g_kernel_pgt_pbase);
|
binfo("mmu_enable: satp=%" PRIuPTR "\n", g_kernel_pgt_pbase);
|
||||||
mmu_enable(g_kernel_pgt_pbase, 0);
|
mmu_enable(g_kernel_pgt_pbase, 0);
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,17 @@
|
|||||||
$ ./tools/configure.sh rv-virt:nsh
|
$ ./tools/configure.sh rv-virt:nsh
|
||||||
$ make V=1 -j7
|
$ make V=1 -j7
|
||||||
|
|
||||||
3.2 Configure and build NuttX for BUILD_KERNEL
|
3.2 Configure and build NuttX for BUILD_KERNEL, 64-bit or 32-bit
|
||||||
|
|
||||||
$ mkdir ./nuttx; cd ./nuttx
|
$ mkdir ./nuttx; cd ./nuttx
|
||||||
$ git clone https://github.com/apache/nuttx.git nuttx
|
$ git clone https://github.com/apache/nuttx.git nuttx
|
||||||
$ git clone https://github.com/apache/nuttx-apps.git apps
|
$ git clone https://github.com/apache/nuttx-apps.git apps
|
||||||
$ cd nuttx
|
$ cd nuttx
|
||||||
$ make distclean
|
$ make distclean
|
||||||
$ ./tools/configure.sh rv-virt:knsh64
|
$ # For 64-bit build.
|
||||||
|
$ ./tools/configure.sh rv-virt:knsh64
|
||||||
|
$ # For 32-bit build.
|
||||||
|
$ ./tools/configure.sh rv-virt:knsh32
|
||||||
$ make V=1 -j7
|
$ make V=1 -j7
|
||||||
$ make export V=1
|
$ make export V=1
|
||||||
$ cd ../apps
|
$ cd ../apps
|
||||||
|
87
boards/risc-v/qemu-rv/rv-virt/configs/knsh32/defconfig
Normal file
87
boards/risc-v/qemu-rv/rv-virt/configs/knsh32/defconfig
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#
|
||||||
|
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||||
|
#
|
||||||
|
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||||
|
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||||
|
# modifications.
|
||||||
|
#
|
||||||
|
# CONFIG_DISABLE_OS_API is not set
|
||||||
|
# CONFIG_NSH_DISABLE_LOSMART is not set
|
||||||
|
CONFIG_16550_ADDRWIDTH=0
|
||||||
|
CONFIG_16550_UART0=y
|
||||||
|
CONFIG_16550_UART0_BASE=0x10000000
|
||||||
|
CONFIG_16550_UART0_CLOCK=3686400
|
||||||
|
CONFIG_16550_UART0_IRQ=35
|
||||||
|
CONFIG_16550_UART0_SERIAL_CONSOLE=y
|
||||||
|
CONFIG_16550_UART=y
|
||||||
|
CONFIG_ARCH="risc-v"
|
||||||
|
CONFIG_ARCH_ADDRENV=y
|
||||||
|
CONFIG_ARCH_BOARD="rv-virt"
|
||||||
|
CONFIG_ARCH_BOARD_QEMU_RV_VIRT=y
|
||||||
|
CONFIG_ARCH_CHIP="qemu-rv"
|
||||||
|
CONFIG_ARCH_CHIP_QEMU_RV32=y
|
||||||
|
CONFIG_ARCH_CHIP_QEMU_RV=y
|
||||||
|
CONFIG_ARCH_CHIP_QEMU_RV_ISA_A=y
|
||||||
|
CONFIG_ARCH_CHIP_QEMU_RV_ISA_C=y
|
||||||
|
CONFIG_ARCH_CHIP_QEMU_RV_ISA_M=y
|
||||||
|
CONFIG_ARCH_DATA_NPAGES=128
|
||||||
|
CONFIG_ARCH_DATA_VBASE=0xC0400000
|
||||||
|
CONFIG_ARCH_HEAP_NPAGES=128
|
||||||
|
CONFIG_ARCH_HEAP_VBASE=0xC0800000
|
||||||
|
CONFIG_ARCH_INTERRUPTSTACK=2048
|
||||||
|
CONFIG_ARCH_KERNEL_STACKSIZE=3072
|
||||||
|
CONFIG_ARCH_PGPOOL_MAPPING=y
|
||||||
|
CONFIG_ARCH_PGPOOL_PBASE=0x80800000
|
||||||
|
CONFIG_ARCH_PGPOOL_SIZE=4194304
|
||||||
|
CONFIG_ARCH_PGPOOL_VBASE=0x80800000
|
||||||
|
CONFIG_ARCH_RISCV=y
|
||||||
|
CONFIG_ARCH_STACKDUMP=y
|
||||||
|
CONFIG_ARCH_TEXT_NPAGES=128
|
||||||
|
CONFIG_ARCH_TEXT_VBASE=0xC0000000
|
||||||
|
CONFIG_ARCH_USE_MMU=y
|
||||||
|
CONFIG_ARCH_USE_MPU=y
|
||||||
|
CONFIG_ARCH_USE_S_MODE=y
|
||||||
|
CONFIG_BOARD_LOOPSPERMSEC=6366
|
||||||
|
CONFIG_BUILD_KERNEL=y
|
||||||
|
CONFIG_DEV_ZERO=y
|
||||||
|
CONFIG_ELF=y
|
||||||
|
CONFIG_EXAMPLES_HELLO=m
|
||||||
|
CONFIG_FS_HOSTFS=y
|
||||||
|
CONFIG_FS_PROCFS=y
|
||||||
|
CONFIG_IDLETHREAD_STACKSIZE=3072
|
||||||
|
CONFIG_INIT_FILEPATH="/system/bin/init"
|
||||||
|
CONFIG_INIT_MOUNT=y
|
||||||
|
CONFIG_INIT_MOUNT_DATA="fs=../apps"
|
||||||
|
CONFIG_INIT_MOUNT_FLAGS=0x1
|
||||||
|
CONFIG_INIT_MOUNT_FSTYPE="hostfs"
|
||||||
|
CONFIG_INIT_MOUNT_SOURCE=""
|
||||||
|
CONFIG_INIT_MOUNT_TARGET="/system"
|
||||||
|
CONFIG_INIT_STACKSIZE=3072
|
||||||
|
CONFIG_INTELHEX_BINARY=y
|
||||||
|
CONFIG_LIBC_ENVPATH=y
|
||||||
|
CONFIG_LIBC_EXECFUNCS=y
|
||||||
|
CONFIG_LIBC_PERROR_STDOUT=y
|
||||||
|
CONFIG_LIBC_STRERROR=y
|
||||||
|
CONFIG_MM_PGALLOC=y
|
||||||
|
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
|
||||||
|
CONFIG_NSH_ARCHINIT=y
|
||||||
|
CONFIG_NSH_FILEIOSIZE=512
|
||||||
|
CONFIG_NSH_FILE_APPS=y
|
||||||
|
CONFIG_NSH_READLINE=y
|
||||||
|
CONFIG_PATH_INITIAL="/system/bin"
|
||||||
|
CONFIG_RAM_SIZE=4194304
|
||||||
|
CONFIG_RAM_START=0x80400000
|
||||||
|
CONFIG_READLINE_CMD_HISTORY=y
|
||||||
|
CONFIG_RISCV_SEMIHOSTING_HOSTFS=y
|
||||||
|
CONFIG_RR_INTERVAL=200
|
||||||
|
CONFIG_SCHED_LPWORK=y
|
||||||
|
CONFIG_SCHED_WAITPID=y
|
||||||
|
CONFIG_SERIAL_UART_ARCH_MMIO=y
|
||||||
|
CONFIG_START_MONTH=12
|
||||||
|
CONFIG_START_YEAR=2021
|
||||||
|
CONFIG_SYMTAB_ORDEREDBYNAME=y
|
||||||
|
CONFIG_SYSLOG_TIMESTAMP=y
|
||||||
|
CONFIG_SYSTEM_NSH=y
|
||||||
|
CONFIG_SYSTEM_NSH_PROGNAME="init"
|
||||||
|
CONFIG_TESTING_GETPRIME=y
|
||||||
|
CONFIG_USEC_PER_TICK=1000
|
@ -24,7 +24,11 @@ include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs
|
|||||||
|
|
||||||
ifeq ($(CONFIG_ARCH_CHIP_QEMU_RV),y)
|
ifeq ($(CONFIG_ARCH_CHIP_QEMU_RV),y)
|
||||||
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||||
LDSCRIPT = ld-kernel.script
|
ifeq ($(CONFIG_ARCH_CHIP_QEMU_RV64),y)
|
||||||
|
LDSCRIPT = ld-kernel64.script
|
||||||
|
else
|
||||||
|
LDSCRIPT = ld-kernel32.script
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
LDSCRIPT = ld.script
|
LDSCRIPT = ld.script
|
||||||
endif
|
endif
|
||||||
|
143
boards/risc-v/qemu-rv/rv-virt/scripts/ld-kernel32.script
Normal file
143
boards/risc-v/qemu-rv/rv-virt/scripts/ld-kernel32.script
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* boards/risc-v/qemu-rv/rv-virt/scripts/ld.script
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
kflash (rx) : ORIGIN = 0x80000000, LENGTH = 4096K /* w/ cache */
|
||||||
|
ksram (rwx) : ORIGIN = 0x80400000, LENGTH = 4096K /* w/ cache */
|
||||||
|
pgram (rwx) : ORIGIN = 0x80800000, LENGTH = 4096K /* w/ cache */
|
||||||
|
}
|
||||||
|
|
||||||
|
OUTPUT_ARCH("riscv")
|
||||||
|
|
||||||
|
/* Provide the kernel boundaries */
|
||||||
|
|
||||||
|
__kflash_start = ORIGIN(kflash);
|
||||||
|
__kflash_size = LENGTH(kflash);
|
||||||
|
__ksram_start = ORIGIN(ksram);
|
||||||
|
__ksram_size = LENGTH(ksram);
|
||||||
|
__ksram_end = ORIGIN(ksram) + LENGTH(ksram);
|
||||||
|
|
||||||
|
/* Page heap */
|
||||||
|
|
||||||
|
__pgheap_start = ORIGIN(pgram);
|
||||||
|
__pgheap_size = LENGTH(pgram);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000000;
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
_stext = . ;
|
||||||
|
*(.text)
|
||||||
|
*(.text.*)
|
||||||
|
*(.gnu.warning)
|
||||||
|
*(.stub)
|
||||||
|
*(.glue_7)
|
||||||
|
*(.glue_7t)
|
||||||
|
*(.jcr)
|
||||||
|
|
||||||
|
/* C++ support: The .init and .fini sections contain specific logic
|
||||||
|
* to manage static constructors and destructors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
*(.init) /* Old ABI */
|
||||||
|
*(.fini) /* Old ABI */
|
||||||
|
_etext = . ;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
_srodata = . ;
|
||||||
|
*(.rodata)
|
||||||
|
*(.rodata1)
|
||||||
|
*(.rodata.*)
|
||||||
|
*(.gnu.linkonce.r*)
|
||||||
|
_erodata = . ;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tdata : {
|
||||||
|
_stdata = ABSOLUTE(.);
|
||||||
|
*(.tdata .tdata.* .gnu.linkonce.td.*);
|
||||||
|
_etdata = ABSOLUTE(.);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tbss : {
|
||||||
|
_stbss = ABSOLUTE(.);
|
||||||
|
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
|
||||||
|
_etbss = ABSOLUTE(.);
|
||||||
|
}
|
||||||
|
|
||||||
|
_eronly = ABSOLUTE(.);
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
_sdata = . ;
|
||||||
|
*(.data)
|
||||||
|
*(.data1)
|
||||||
|
*(.data.*)
|
||||||
|
*(.gnu.linkonce.d*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_edata = . ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Page tables here, align to 4K boundary */
|
||||||
|
|
||||||
|
.pgtables (NOLOAD) : ALIGN(0x1000) {
|
||||||
|
*(.pgtables)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} > ksram
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
_sbss = . ;
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
*(.sbss)
|
||||||
|
*(.sbss.*)
|
||||||
|
*(.gnu.linkonce.b*)
|
||||||
|
*(COMMON)
|
||||||
|
_ebss = . ;
|
||||||
|
} > ksram
|
||||||
|
|
||||||
|
/* Stack top */
|
||||||
|
|
||||||
|
.stack_top : {
|
||||||
|
. = ALIGN(32);
|
||||||
|
_ebss = ABSOLUTE(.);
|
||||||
|
} > ksram
|
||||||
|
|
||||||
|
/* Stabs debugging sections. */
|
||||||
|
|
||||||
|
.stab 0 : { *(.stab) }
|
||||||
|
.stabstr 0 : { *(.stabstr) }
|
||||||
|
.stab.excl 0 : { *(.stab.excl) }
|
||||||
|
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||||
|
.stab.index 0 : { *(.stab.index) }
|
||||||
|
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||||
|
.comment 0 : { *(.comment) }
|
||||||
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||||
|
.debug_info 0 : { *(.debug_info) }
|
||||||
|
.debug_line 0 : { *(.debug_line) }
|
||||||
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
|
}
|
@ -85,6 +85,7 @@ static struct rname_code_s _rname_table[] =
|
|||||||
{"JAL", R_RISCV_JAL},
|
{"JAL", R_RISCV_JAL},
|
||||||
{"RVC_JUMP", R_RISCV_RVC_JUMP},
|
{"RVC_JUMP", R_RISCV_RVC_JUMP},
|
||||||
{"RVC_BRANCH", R_RISCV_RVC_BRANCH},
|
{"RVC_BRANCH", R_RISCV_RVC_BRANCH},
|
||||||
|
{"32_PCREL", R_RISCV_32_PCREL},
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -540,6 +541,19 @@ int up_relocateadd(const Elf_Rela *rel, const Elf_Sym *sym,
|
|||||||
offset, offset, val);
|
offset, offset, val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case R_RISCV_32_PCREL:
|
||||||
|
{
|
||||||
|
/* P.29 https://github.com/riscv-non-isa/riscv-elf-psabi-doc */
|
||||||
|
|
||||||
|
binfo("%s at %08" PRIxPTR " [%08" PRIx32 "] "
|
||||||
|
"to sym=%p st_value=%08lx\n",
|
||||||
|
_get_rname(relotype),
|
||||||
|
addr, _get_val((uint16_t *)addr),
|
||||||
|
sym, sym->st_value);
|
||||||
|
|
||||||
|
addr = (long)sym->st_value + (long)rel->r_addend - (long)addr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case R_RISCV_ADD32:
|
case R_RISCV_ADD32:
|
||||||
{
|
{
|
||||||
*(uint32_t *)addr += (uint32_t)(sym->st_value + rel->r_addend);
|
*(uint32_t *)addr += (uint32_t)(sym->st_value + rel->r_addend);
|
||||||
|
Loading…
Reference in New Issue
Block a user