arch:rv64:c906:add PMP, change mem map for protect build.

Signed-off-by: hotislandn <hotislandn@hotmail.com>
This commit is contained in:
hotislandn 2021-03-27 22:32:10 +08:00 committed by Xiang Xiao
parent 20ce2f274a
commit 6aa86b469c
16 changed files with 326 additions and 77 deletions

View File

@ -353,6 +353,18 @@
asm volatile("csrc " CSR_STR(reg) ", %0" :: "rK"(bits)); \ asm volatile("csrc " CSR_STR(reg) ", %0" :: "rK"(bits)); \
}) })
/* In pmpcfg (PMP configuration) register */
#define PMPCFG_R (1 << 0) /* readable ? */
#define PMPCFG_W (1 << 1) /* writeable ? */
#define PMPCFG_X (1 << 2) /* excutable ? */
#define PMPCFG_A_OFF (0 << 3) /* null region (disabled) */
#define PMPCFG_A_TOR (1 << 3) /* top of range */
#define PMPCFG_A_NA4 (2 << 3) /* naturally aligned four-byte region */
#define PMPCFG_A_NAPOT (3 << 3) /* naturally aligned power-of-two region */
#define PMPCFG_A_MASK (3 << 3) /* address-matching mode mask */
#define PMPCFG_L (1 << 7) /* locked ? */
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/

View File

@ -55,7 +55,7 @@ CHIP_CSRCS += c906_start.c c906_timerisr.c
ifeq ($(CONFIG_BUILD_PROTECTED),y) ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c
CMN_CSRCS += riscv_signal_dispatch.c CMN_CSRCS += riscv_signal_dispatch.c riscv_pmp.c
CMN_UASRCS += riscv_signal_handler.S CMN_UASRCS += riscv_signal_handler.S
CHIP_CSRCS += c906_userspace.c CHIP_CSRCS += c906_userspace.c

View File

@ -37,7 +37,7 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#define SRAM1_END CONFIG_RAM_END #define KRAM_END CONFIG_RAM_END
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
@ -61,54 +61,45 @@
* .data region. Size determined at link time. * .data region. Size determined at link time.
* .bss region Size determined at link time. * .bss region Size determined at link time.
* IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE.
* Heap. Extends to the end of SRAM. * Heap. Extends to the end of User SRAM.
* *
* The following memory map is assumed for the kernel build: * The following memory map is assumed for the protect build.
* The kernel and user space have it's own dedicated heap space.
* *
* User .data region Size determined at link time
* User .bss region Size determined at link time
* User heap Extends to the end of User SRAM
* Kernel .data region Size determined at link time * Kernel .data region Size determined at link time
* Kernel .bss region Size determined at link time * Kernel .bss region Size determined at link time
* Kernel IDLE thread stack Size determined by CONFIG_IDLETHREAD_STACKSIZE * Kernel IDLE thread stack Size determined by CONFIG_IDLETHREAD_STACKSIZE
* Padding for alignment
* User .data region Size determined at link time
* User .bss region Size determined at link time
* Kernel heap Size determined by CONFIG_MM_KERNEL_HEAPSIZE * Kernel heap Size determined by CONFIG_MM_KERNEL_HEAPSIZE
* User heap Extends to the end of SRAM
* *
****************************************************************************/ ****************************************************************************/
void up_allocate_heap(FAR void **heap_start, size_t *heap_size) void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
{ {
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) #if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
/* Get the unaligned size and position of the user-space heap. /* Get the size and position of the user-space heap.
* This heap begins after the user-space .bss section at an offset * This heap begins after the user-space .bss section.
* of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment).
*/ */
uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend;
CONFIG_MM_KERNEL_HEAPSIZE; size_t usize = (uintptr_t)USERSPACE->us_heapend - ubase;
size_t usize = SRAM1_END - ubase;
DEBUGASSERT(ubase < (uintptr_t)SRAM1_END);
/* Adjust that size to account for MPU alignment requirements.
* NOTE that there is an implicit assumption that the SRAM1_END
* is aligned to the MPU requirement.
*/
ubase = SRAM1_END - usize;
/* Return the user-space heap settings */ /* Return the user-space heap settings */
*heap_start = (FAR void *)ubase; *heap_start = (FAR void *)ubase;
*heap_size = usize; *heap_size = usize;
/* TODO: Allow user-mode access to the user heap memory in PMP */ /* Allow user-mode access to the user heap memory in PMP
* is already done in c906_userspace().
*/
#else #else
/* Return the heap settings */ /* Return the heap settings */
*heap_start = (FAR void *)g_idle_topstack; *heap_start = (FAR void *)g_idle_topstack;
*heap_size = CONFIG_RAM_END - g_idle_topstack; *heap_size = KRAM_END - g_idle_topstack;
#endif #endif
} }
@ -125,31 +116,10 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) #if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) void up_allocate_kheap(FAR void **heap_start, size_t *heap_size)
{ {
/* Get the unaligned size and position of the user-space heap. /* Return the kernel heap settings. */
* This heap begins after the user-space .bss section at an offset
* of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment).
*/
uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend; *heap_start = (FAR void *)g_idle_topstack;
ubase += CONFIG_MM_KERNEL_HEAPSIZE; *heap_size = KRAM_END - g_idle_topstack;
size_t usize = SRAM1_END - ubase;
DEBUGASSERT(ubase < (uintptr_t)SRAM1_END);
/* TODO: Adjust that size to account for MPU alignment requirements.
* NOTE that there is an implicit assumption that the SRAM1_END
* is aligned to the MPU requirement.
*/
ubase = SRAM1_END - usize;
/* Return the kernel heap settings (i.e., the part of the heap region
* that was not dedicated to the user heap).
*/
*heap_start = (FAR void *)USERSPACE->us_bssend;
*heap_size = ubase - (uintptr_t)USERSPACE->us_bssend;
} }
#endif #endif

View File

@ -29,10 +29,31 @@
#include <nuttx/userspace.h> #include <nuttx/userspace.h>
#include "riscv_internal.h"
#include "c906_userspace.h" #include "c906_userspace.h"
#ifdef CONFIG_BUILD_PROTECTED #ifdef CONFIG_BUILD_PROTECTED
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* TODO: get user space mem layout info from ld script or Configuration ? */
#ifndef CONFIG_NUTTX_USERSPACE_SIZE
# define CONFIG_NUTTX_USERSPACE_SIZE (0x00100000)
#endif
#ifndef CONFIG_NUTTX_USERSPACE_RAM_START
# define CONFIG_NUTTX_USERSPACE_RAM_START (0x00100000)
#endif
#ifndef CONFIG_NUTTX_USERSPACE_RAM_SIZE
# define CONFIG_NUTTX_USERSPACE_RAM_SIZE (0x00100000)
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@ -82,9 +103,25 @@ void c906_userspace(void)
*dest++ = *src++; *dest++ = *src++;
} }
/* TODO: /* Configure the PMP to permit user-space access to its ROM and RAM.
* Configure the PMP to permit user-space access to its ROM and RAM * Now this is done by simply adding the whole memory area to PMP.
* 1. no access for the 1st 4KB
* 2. "RX" for the left space until 1MB
* 3. "RW" for the user RAM area
* TODO: more accurate memory size control.
*/ */
riscv_config_pmp_region(0, PMPCFG_A_NAPOT,
0,
0x1000);
riscv_config_pmp_region(1, PMPCFG_A_TOR | PMPCFG_X | PMPCFG_R,
0 + CONFIG_NUTTX_USERSPACE_SIZE,
0);
riscv_config_pmp_region(2, PMPCFG_A_NAPOT | PMPCFG_W | PMPCFG_R,
CONFIG_NUTTX_USERSPACE_RAM_START,
CONFIG_NUTTX_USERSPACE_RAM_SIZE);
} }
#endif /* CONFIG_BUILD_PROTECTED */ #endif /* CONFIG_BUILD_PROTECTED */

View File

@ -203,6 +203,11 @@ void riscv_restorefpu(const uint32_t *regs);
# define riscv_restorefpu(regs) # define riscv_restorefpu(regs)
#endif #endif
/* RISC-V PMP Config ********************************************************/
void riscv_config_pmp_region(uintptr_t region, uintptr_t attr,
uintptr_t base, uintptr_t size);
/* Power management *********************************************************/ /* Power management *********************************************************/
#ifdef CONFIG_PM #ifdef CONFIG_PM

View File

@ -0,0 +1,209 @@
/****************************************************************************
* arch/risc-v/src/common/riscv_pmp.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <arch/csr.h>
#include "riscv_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define PMP_CFG_BITS_CNT (8)
#define PMP_CFG_FLAG_MASK (0xFF)
#define PMP_CFG_CNT_IN_REG (__riscv_xlen / PMP_CFG_BITS_CNT)
#define PMP_MASK_SET_ONE_REGION(region, attr, reg) \
do { \
uintptr_t offset = region % PMP_CFG_CNT_IN_REG; \
reg &= ~(PMP_CFG_FLAG_MASK << (offset * PMP_CFG_BITS_CNT)); \
reg |= attr << (offset * PMP_CFG_BITS_CNT); \
} while(0);
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: riscv_config_pmp_region
*
* Description:
* This function will set the specific PMP region with the desired cfg.
*
* Input Parameters:
* region - The region index number.
* attr - The region configurations.
* base - The base address of the region.
* size - The memory length of the region.
* For the NAPOT mode, the base address must aligned to the size boundary,
* and the size must be power-of-two according to the the PMP spec.
*
* Returned Value:
* None.
*
****************************************************************************/
void riscv_config_pmp_region(uintptr_t region, uintptr_t attr,
uintptr_t base, uintptr_t size)
{
uintptr_t addr = 0;
uintptr_t cfg = 0;
/* TODO: check the base address alignment and size */
addr = base >> 2;
if (PMPCFG_A_NAPOT == (attr & PMPCFG_A_MASK))
{
addr |= (size - 1) >> 3;
}
switch (region)
{
case 0:
WRITE_CSR(pmpaddr0, addr);
break;
case 1:
WRITE_CSR(pmpaddr1, addr);
break;
case 2:
WRITE_CSR(pmpaddr2, addr);
break;
case 3:
WRITE_CSR(pmpaddr3, addr);
break;
case 4:
WRITE_CSR(pmpaddr4, addr);
break;
case 5:
WRITE_CSR(pmpaddr5, addr);
break;
case 6:
WRITE_CSR(pmpaddr6, addr);
break;
case 7:
WRITE_CSR(pmpaddr7, addr);
break;
case 8:
WRITE_CSR(pmpaddr8, addr);
break;
case 9:
WRITE_CSR(pmpaddr9, addr);
break;
case 10:
WRITE_CSR(pmpaddr10, addr);
break;
case 11:
WRITE_CSR(pmpaddr11, addr);
break;
case 12:
WRITE_CSR(pmpaddr12, addr);
break;
case 13:
WRITE_CSR(pmpaddr13, addr);
break;
case 14:
WRITE_CSR(pmpaddr14, addr);
break;
case 15:
WRITE_CSR(pmpaddr15, addr);
break;
default:
break;
}
# if (__riscv_xlen == 32)
switch (region)
{
case 0 ... 3:
cfg = READ_CSR(pmpcfg0);
PMP_MASK_SET_ONE_REGION(region, attr, cfg);
WRITE_CSR(pmpcfg0, cfg);
break;
case 4 ... 7:
cfg = READ_CSR(pmpcfg1);
PMP_MASK_SET_ONE_REGION(region, attr, cfg);
WRITE_CSR(pmpcfg1, cfg);
break;
case 8 ... 11:
cfg = READ_CSR(pmpcfg2);
PMP_MASK_SET_ONE_REGION(region, attr, cfg);
WRITE_CSR(pmpcfg2, cfg);
break;
case 12 ... 15:
cfg = READ_CSR(pmpcfg3);
PMP_MASK_SET_ONE_REGION(region, attr, cfg);
WRITE_CSR(pmpcfg3, cfg);
break;
default:
break;
}
# elif (__riscv_xlen == 64)
switch (region)
{
case 0 ... 7:
cfg = READ_CSR(pmpcfg0);
PMP_MASK_SET_ONE_REGION(region, attr, cfg);
WRITE_CSR(pmpcfg0, cfg);
break;
case 8 ... 15:
cfg = READ_CSR(pmpcfg2);
PMP_MASK_SET_ONE_REGION(region, attr, cfg);
WRITE_CSR(pmpcfg2, cfg);
break;
default:
break;
}
# else
# error "XLEN of risc-v not supported"
# endif
/* fence is needed when page-based virtual memory is implemented */
__asm volatile("sfence.vma x0, x0" : : : "memory");
}

View File

@ -44,8 +44,8 @@ CONFIG_NSH_FILE_APPS=y
CONFIG_NSH_READLINE=y CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=4 CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=262144 CONFIG_RAM_SIZE=1048576
CONFIG_RAM_START=0x00180000 CONFIG_RAM_START=0x00300000
CONFIG_RAW_BINARY=y CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200 CONFIG_RR_INTERVAL=200

View File

@ -40,8 +40,8 @@ CONFIG_NSH_DISABLE_UMOUNT=y
CONFIG_NSH_READLINE=y CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=4 CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=262144 CONFIG_RAM_SIZE=1048576
CONFIG_RAM_START=0x00180000 CONFIG_RAM_START=0x00300000
CONFIG_RAW_BINARY=y CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200 CONFIG_RR_INTERVAL=200

View File

@ -41,11 +41,11 @@ CONFIG_NSH_DISABLE_RMDIR=y
CONFIG_NSH_DISABLE_UMOUNT=y CONFIG_NSH_DISABLE_UMOUNT=y
CONFIG_NSH_READLINE=y CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y CONFIG_NSH_STRERROR=y
CONFIG_NUTTX_USERSPACE=0x00080000 CONFIG_NUTTX_USERSPACE=0x00001000
CONFIG_PASS1_BUILDIR="boards/risc-v/c906/smartl-c906/kernel" CONFIG_PASS1_BUILDIR="boards/risc-v/c906/smartl-c906/kernel"
CONFIG_PREALLOC_TIMERS=4 CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=1572864 CONFIG_RAM_SIZE=1048576
CONFIG_RAM_START=0x00180000 CONFIG_RAM_START=0x00300000
CONFIG_RAW_BINARY=y CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200 CONFIG_RR_INTERVAL=200

View File

@ -39,8 +39,8 @@ CONFIG_NSH_DISABLE_UMOUNT=y
CONFIG_NSH_READLINE=y CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=4 CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=262144 CONFIG_RAM_SIZE=1048576
CONFIG_RAM_START=0x00180000 CONFIG_RAM_START=0x00300000
CONFIG_RAW_BINARY=y CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200 CONFIG_RR_INTERVAL=200

View File

@ -43,7 +43,7 @@
# error "CONFIG_NUTTX_USERSPACE not defined" # error "CONFIG_NUTTX_USERSPACE not defined"
#endif #endif
#if CONFIG_NUTTX_USERSPACE != 0x00080000 #if CONFIG_NUTTX_USERSPACE != 0x00001000
# error "CONFIG_NUTTX_USERSPACE must match the value in memory.ld" # error "CONFIG_NUTTX_USERSPACE must match the value in memory.ld"
#endif #endif
@ -71,6 +71,8 @@ extern uint32_t _edata; /* End+1 of .data */
extern uint32_t _sbss; /* Start of .bss */ extern uint32_t _sbss; /* Start of .bss */
extern uint32_t _ebss; /* End+1 of .bss */ extern uint32_t _ebss; /* End+1 of .bss */
extern uintptr_t *__ld_usram_end; /* End+1 of user ram section */
/* This is the user space entry point */ /* This is the user space entry point */
int CONFIG_USER_ENTRYPOINT(int argc, char *argv[]); int CONFIG_USER_ENTRYPOINT(int argc, char *argv[]);
@ -88,6 +90,8 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) =
.us_bssstart = (uintptr_t)&_sbss, .us_bssstart = (uintptr_t)&_sbss,
.us_bssend = (uintptr_t)&_ebss, .us_bssend = (uintptr_t)&_ebss,
.us_heapend = (uintptr_t)&__ld_usram_end,
/* Memory manager heap structure */ /* Memory manager heap structure */
.us_heap = &g_mmheap, .us_heap = &g_mmheap,

View File

@ -20,8 +20,8 @@
MEMORY MEMORY
{ {
progmem (rx) : ORIGIN = 0x00000000, LENGTH = 1024K /* w/ cache */ progmem (rx) : ORIGIN = 0x00200000, LENGTH = 1024K /* w/ cache */
sram (rwx) : ORIGIN = 0x00100000, LENGTH = 1024K /* w/ cache */ sram (rwx) : ORIGIN = 0x00300000, LENGTH = 1024K /* w/ cache */
} }
OUTPUT_ARCH("riscv") OUTPUT_ARCH("riscv")

View File

@ -20,8 +20,8 @@
MEMORY MEMORY
{ {
progmem (rx) : ORIGIN = 0x00000000, LENGTH = 1024K /* w/ cache */ progmem (rx) : ORIGIN = 0x00200000, LENGTH = 1024K /* w/ cache */
sram (rwx) : ORIGIN = 0x00100000, LENGTH = 1024K /* w/ cache */ sram (rwx) : ORIGIN = 0x00300000, LENGTH = 1024K /* w/ cache */
} }
OUTPUT_ARCH("riscv") OUTPUT_ARCH("riscv")

View File

@ -20,15 +20,16 @@
/* Reg Access Start addr End addr Size /* Reg Access Start addr End addr Size
* QEMU CPU w/ cache 0x00000000 - 0x003fffff : 4MB * QEMU CPU w/ cache 0x00000000 - 0x003fffff : 4MB
* QEMU CPU w/o cache 0x1f000000 - 0x1f01ffff : 128KB
*/ */
MEMORY MEMORY
{ {
kflash (rx) : ORIGIN = 0x00000000, LENGTH = 512K /* w/ cache */ uflash (rx) : ORIGIN = 0x00001000, LENGTH = 1020K /* w/ cache */
uflash (rx) : ORIGIN = 0x00080000, LENGTH = 512K /* w/ cache */ usram (rwx) : ORIGIN = 0x00100000, LENGTH = 1024K /* w/ cache */
xflash (rx) : ORIGIN = 0x00100000, LENGTH = 512K /* w/ cache */ xflash (rx) : ORIGIN = 0x1f000000, LENGTH = 64K /* w/o cache */
ksram (rwx) : ORIGIN = 0x00180000, LENGTH = 512K /* w/ cache */ kflash (rx) : ORIGIN = 0x00200000, LENGTH = 1024K /* w/ cache */
usram (rwx) : ORIGIN = 0x00200000, LENGTH = 512K /* w/ cache */ ksram (rwx) : ORIGIN = 0x00300000, LENGTH = 1024K /* w/ cache */
xsram (rwx) : ORIGIN = 0x00280000, LENGTH = 512K /* w/ cache */ xsram (rwx) : ORIGIN = 0x1f010000, LENGTH = 64K /* w/o cache */
} }

View File

@ -20,15 +20,16 @@
/* Reg Access Start addr End addr Size /* Reg Access Start addr End addr Size
* QEMU CPU w/ cache 0x00000000 - 0x003fffff : 4MB * QEMU CPU w/ cache 0x00000000 - 0x003fffff : 4MB
* QEMU CPU w/o cache 0x1f000000 - 0x1f01ffff : 128KB
*/ */
MEMORY MEMORY
{ {
kflash (rx) : ORIGIN = 0x00000000, LENGTH = 512K /* w/ cache */ uflash (rx) : ORIGIN = 0x00001000, LENGTH = 1020K /* w/ cache */
uflash (rx) : ORIGIN = 0x00080000, LENGTH = 512K /* w/ cache */ usram (rwx) : ORIGIN = 0x00100000, LENGTH = 1024K /* w/ cache */
xflash (rx) : ORIGIN = 0x00100000, LENGTH = 512K /* w/ cache */ xflash (rx) : ORIGIN = 0x1f000000, LENGTH = 64K /* w/o cache */
ksram (rwx) : ORIGIN = 0x00180000, LENGTH = 512K /* w/ cache */ kflash (rx) : ORIGIN = 0x00200000, LENGTH = 1024K /* w/ cache */
usram (rwx) : ORIGIN = 0x00200000, LENGTH = 512K /* w/ cache */ ksram (rwx) : ORIGIN = 0x00300000, LENGTH = 1024K /* w/ cache */
xsram (rwx) : ORIGIN = 0x00280000, LENGTH = 512K /* w/ cache */ xsram (rwx) : ORIGIN = 0x1f010000, LENGTH = 64K /* w/o cache */
} }

View File

@ -26,6 +26,16 @@ OUTPUT_ARCH("riscv")
SECTIONS SECTIONS
{ {
/* section info */
__ld_uflash_start = ORIGIN(uflash);
__ld_uflash_end = ORIGIN(uflash)+ LENGTH(uflash);
__ld_uflash_size = LENGTH(uflash);
__ld_usram_start = ORIGIN(usram);
__ld_usram_end = ORIGIN(usram)+ LENGTH(usram);
__ld_usram_size = LENGTH(usram);
.userspace : { .userspace : {
*(.userspace) *(.userspace)
} > uflash } > uflash