risc-v/k230: initial Asymmetric Multi-Processing support

K230 chip has two T-Head C908 RiscV cores, previously we run NuttX
on either little or big cores. This patch runs NuttX on both cores
with OpenAMP support via the RPTUN driver.

New additions:

- in arch/risc-v/src/k230
  - k230_rptun.c              K230 RPTUN driver
  - k230_rptun.h              K230 RPTUN driver header file

- in baords/risc-v/k230/canmv230
  - configs/master            Build config for master node
  - configs/remote            Build config for remote node
  - scripts/ld-rptun.script   Build script for RPTUN

Major changes:

- arch/risc-v/Kconfig         Select NUTTSBI_LATE_INIT upon NUTTSBI
- in arch/risc-v/include
  - k230/irq.h                Add UART3 IRQ defs
- in arch/risc-v/src/k230
  - Kconfig                   Add RPTUN related config items
  - Make.defs                 Add k230-rptun.c to sources
  - hardware/k230_memorymap.h Add K230 device and CSR defs
  - k230_hart.c               Add hart ctrl for RPTUN
  - k230_hart.h               Add hart ctrl for RPTUN
  - k230_mm_init.c            Add Svpmbt to support RPTUN
  - k230_start.c              Revised to support RPMsg UART
- in boards/risc-v/k230/canmv230
  - scripts/Make.defs         Add RPTUN script selection
  - src/canmv_init.c          Add RPTUN and RPMsg_UART initialization
- in Documentation/platforms/risc-v/k230/boards/canmv230
  - index.rst                 Add AMP usage information.

Signed-off-by: Yanfeng Liu <yfliu2008@qq.com>
This commit is contained in:
Yanfeng Liu 2024-02-08 14:21:08 +08:00 committed by Alan Carvalho de Assis
parent 4a85fbfd09
commit a4b22fe999
18 changed files with 1271 additions and 118 deletions

View File

@ -6,19 +6,22 @@ The `CanMV K230 <https://developer.canaan-creative.com/k230/dev/zh/CanMV_K230_%E
The `K230 SDK <https://github.com/kendryte/k230_sdk>`_ contains source code, libraries and user guides for booting up an AMP enviroment with Linux on CPU0 and RT-Thread on CPU1.
K230 boots from CPU0 and loads U-Boot into DRAM first, then U-Boot kicks off OpenSBI wrapped Linux/RTT OS images on respective CPU cores accordingly.
K230 boots from CPU0 and loads U-Boot SPL into DRAM first, then U-Boot kicks off OpenSBI wrapped Linux/RTT OS images on respective CPU cores accordingly.
The K230 U-Boot runs in machine mode, thus it supports flat, protected or kernel `build modes <https://nuttx.apache.org/docs/latest/implementation/processes_vs_tasks.html>`_. The kernel build mode further allows use of OpenSBI or not.
The K230 U-Boot kicks off firmwares in machine mode, thus it allows flat, protected or kernel
NuttX `build modes <https://nuttx.apache.org/docs/latest/implementation/processes_vs_tasks.html>`_. The kernel build mode further works with OpenSBI or a builtin minimal SBI layer.
Preparations
============
Take the prebuilt CanMV-k230 boot image from `here <https://gitee.com/yf1972/filexfers/tree/canmv230-tools-for-nuttx-v1.2>`_ as the default K230 SDK doesn't support RiscV standard PTE format at least till v1.2. This package also contains an extract of the OpenSBI from K230 SDK v1.2 release, which is needed to wrap Nuttx kernel build binary.
Take the prebuilt CanMV-k230 boot image from `here <https://gitee.com/yf1972/filexfers/tree/canmv230-tools-for-nuttx-v1.2>`_ as the default K230 SDK doesn't support RiscV standard PTE format at least till v1.2. The package also contains an extract of the OpenSBI from K230 SDK v1.2 release, which is needed to wrap the `canmv230/knsh` kernel build. The K230 SBI extract is
also available at `this Github repository <https://github.com/yf13/k230osbi>`_, it will updated
over the time to match updates at NuttX repository.
Make sure that before trying NuttX:
- The board can boot with prebuilt CanMV-k230 image.
- Device console access available (e.g. `minicom -D /dev/ttyACM0`).
- Device console access available (e.g. ``minicom -D /dev/ttyACM0``).
- U-Boot connectivity to TFTP service available.
For below NuttX tests, the microSD card is only used to enter the U-Boot console environment, as NuttX isn't using any storage yet.
@ -26,7 +29,7 @@ For below NuttX tests, the microSD card is only used to enter the U-Boot console
Toolchains
==========
Before building NuttX, download the **RISC-V Toolchain riscv64-unknown-elf** from `XPack <https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack>`_ or get the stock "gcc-riscv64-unknown-elf" via `apt` on Ubuntu.
To build NuttX, we can use the stock **gcc-riscv64-unknown-elf** toolchain on Ubuntu, or download the RISC-V Toolchain riscv64-unknown-elf from `XPack <https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack>`_.
Building
@ -74,7 +77,7 @@ KERNEL Build
KERNEL build requires two build passes:
- First pass to build kernel w/ dummy ROMFS, then we build the apps and update ROMFS,
- First pass to build kernel and export package so that to build apps as ROMFS.
- Second pass to build the kernel with real ROMFS image containing the apps.
There are two configurations for KERNEL build mode:
@ -82,9 +85,9 @@ There are two configurations for KERNEL build mode:
- The ``canmv230/knsh`` is for use within standard SBI environment.
- The ``canmv230/nsbi`` uses a built-in minimal SBI environment.
The ``canmv230/nsbi`` has smaller footprint and is simpler to use, the ``canmv230/knsh`` is for cases requiring stanard SBI environment.
The ``canmv230/nsbi`` has smaller footprint and is simpler to use, the ``canmv230/knsh`` is more tedious to build and is for situatinos with standard SBI environment.
Take the following steps to build the kernel mode export package:
Take the following steps to build the kernel export package:
.. code:: console
@ -94,7 +97,7 @@ Take the following steps to build the kernel mode export package:
$ make -j4
$ make export # build nuttx-export-*.gz package
With export package, we can move ahead to build the apps:
With export package, we can then build the apps and ROMFS:
.. code:: console
@ -112,23 +115,25 @@ Once ROMFS for apps is ready, build the kernel again:
$ cd nuttx
$ make -j4 # build kernel again with real ROMFS
The ``nuttx.bin`` is the artifact of kernel build. For ``canmv230/nsbi`` case, simply copy it to the TFTP folder and try on the target.
The ``nuttx.bin`` is the artifact of kernel build. For ``canmv230/nsbi`` case, simply copy it to the TFTP folder then run on the target.
For ``canmv230/knsh`` case, take following steps to wrap the artifact with the OpenSBI extract from the K230 SDK downloaded above:
For ``canmv230/knsh`` case, take additional steps to wrap the artifact with the OpenSBI extract from the K230 SDK downloaded above:
.. code:: console
$ cd $HOME
$ # unpack the OpenSBI extract from K230 SDK
$ # unpack the K230 OpenSBI extract
$ tar xvf canmv230-opensbi-dtb.tar.xz
$ export OSBI=$HOME/opensbi
$ cd /tmp/aaa # use a temporary work folder
$ cd /tmp/aaa # use a temporary folder
$ make -C $OSBI O=$(pwd) PLATFORM=generic \
CROSS_COMPILE=riscv64-unknown-elf- FW_PIC=n K230_LIITLE_CORE=1 \
FW_FDT_PATH=$OSBI/k230.dtb FW_PAYLOAD_PATH=nuttx.bin -j4
$ cp platform/generic/firmware/fw_payload.bin tftp-server-path/nuttx.bin
Please use actual paths on your host for `nuttx.bin` and TFTP folder when running above commands.
Please use actual paths on your host for ``nuttx.bin`` and TFTP folder when running above commands.
This Github `repository <https://github.com/yf13/k230osbi>`_ contains latest version of the K230 OpenSBI extract.
Running
@ -145,6 +150,32 @@ Within U-boot console, load ``nuttx.bin`` from TFTP and run it as shown below:
Then the ``nsh`` console should appear, type ``help`` to see available commands.
Asymmetric Multi Processing
===========================
We can do Asymmetric Multi Processing on K230 using the little core as master and the big core as remote.
Take the ``canmv230/master`` and ``canmv230/remote`` configurations to build the master and remote NuttX images respectively. They are both kernel builds derived from ``canmv230/nsbi`` mentioned above, so we can follow above kernel mode build steps to build them.
Let's put the NuttX image files as ``master.bin`` and ``remote.bin`` respectively on the TFTP folder. To run them on K230 device, do the following from U-Boot console:
.. code:: console
k230# usb start
k230# ping $serverip
k230# tftp 7000000 remote.bin
k230# mw.l 80200000 0 8192
k230# boot_baremetal 1 7000000 $filesize
k230# tftp 8000000 master.bin
k230# go 8000000
Then we should see the "master> " prompt, this is the master console. where we can further run the ``cu`` command and press Return key to see the remote console, within remote console type ``~.`` to get back to the master console.
There is a `session log <https://github.com/apache/nuttx/pull/11673>`_ showing how to enter remote node and check file system status then get back and check master file system status.
Issues
======

View File

@ -302,12 +302,12 @@ config ARCH_CHIP_K230
select ARCH_NEED_ADDRENV_MAPPING
select ARCH_HAVE_S_MODE
select ARCH_HAVE_ELF_EXECUTABLE
select NUTTSBI_LATE_INIT if NUTTSBI
select ONESHOT
select ALARM_ARCH
---help---
Kendryte K230 SoC (RV64GCV and RV64GCVX C908 cores).
config ARCH_CHIP_RISCV_CUSTOM
bool "Custom RISC-V chip"
select ARCH_CHIP_CUSTOM

View File

@ -34,13 +34,15 @@
#ifndef CONFIG_BUILD_KERNEL
# define K230_IRQ_TIMER (RISCV_IRQ_MTIMER)
# define K230_IRQ_UART0 (RISCV_IRQ_MEXT + 16)
# define K230_IRQ_UART3 (RISCV_IRQ_MEXT + 19)
#else
# define K230_IRQ_TIMER (RISCV_IRQ_STIMER)
# define K230_IRQ_UART0 (RISCV_IRQ_SEXT + 16)
# define K230_IRQ_UART3 (RISCV_IRQ_SEXT + 19)
#endif
/* NR_IRQS is needed by NuttX */
#define NR_IRQS (K230_IRQ_UART0 + 1)
#define NR_IRQS (K230_IRQ_UART3 + 1)
#endif /* __ARCH_RISCV_INCLUDE_K230_IRQ_H */

View File

@ -0,0 +1,43 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
if RPTUN
config K230_RPTUN_MASTER
bool "RPTUN master node"
default y if RPTUN_LOADER
default n
config K230_RPTUN_SHM_ADDR
hex "RPTUN share memory address"
default 0x80200000
---help---
RPTUN shared memory start address.
config K230_RPTUN_SHM_SIZE
int "RPTUN share memory size"
default 32768
---help---
RPTUN shared memory size in bytes.
config K230_RPTUN_IPI
bool "use IPI for RPTUN"
default n
depends on K230_IPI
---help---
Use Inter-Processor interruption to improve efficiency.
Not ready yet.
config K230_RPTUN_WORK_DELAY
int "RPTUN work delay"
default 50
depends on !K230_RPTUN_IPI
---help---
Ticks for polling RPTUN. Polling doesn't need IPI.
endif # RPTUN

View File

@ -37,3 +37,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CHIP_CSRCS += k230_userspace.c
endif
ifeq ($(CONFIG_RPTUN),y)
CHIP_CSRCS += k230_rptun.c
endif

View File

@ -25,21 +25,26 @@
* Pre-processor Definitions
****************************************************************************/
/* PLIC/CLINT Base Address **************************************************/
/* Devices Base Address */
#define K230_PLIC_BASE 0xF00000000
#define K230_PLIC_BASE 0xF00000000UL
#define K230_CLINT_BASE (K230_PLIC_BASE + 0x04000000)
#define K230_CPU1_BOOTA 0x91102104UL
#define K230_CPU1_RESET 0x9110100cUL
/* T-Head c908 specific CSR */
#define CSR_MCOR 0x7c2
#define CSR_MENVCFG 0x30a
#define CSR_MXSTATUS 0x7c0
#define CSR_MHCR 0x7c1
#define CSR_MCOR 0x7c2
#define CSR_MCCR2 0x7c3
#define CSR_MHINT 0x7c5
#define CSR_MXSTATUS 0x7c0
#define CSR_MRMR 0x7c6
#define CSR_MRVBR 0x7c7
#define CSR_MSMPR 0x7f3
#define CSR_PLIC_BASE 0xfc1
#define CSR_MAGIC 0x7d9
/* Enable RV PBMT */
#define MENVCFG_PBMT (1ul << 62)
#endif /* __ARCH_RISCV_SRC_K230_HARDWARE_K230_MEMORYMAP_H */

View File

@ -36,17 +36,82 @@
#include "chip.h"
/****************************************************************************
* Public Functions
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_K230_PBMT_THEAD
#define THEAD_PBMT 0x638000
#define XSTATUS THEAD_PBMT
#else
#define RISCV_PBMT 0x438000
#define XSTATUS RISCV_PBMT
#endif
#define XSTATE_MSK ((1 << 30) - 1)
#define MCOR 0x70013
#define MHCR 0x11ff
#define MHINT 0x6e30c
#define MCCR2 0xe0000009
#define MHINT_BIG 0x16e30c
#define MCCR2_BIG 0xe0410009
#define MSMPR 1
#define MHCR_IE_MSK (1 << 0)
#define MHCR_DE_MSK (1 << 1)
#define RISCV_PMBT_EN (1 << 62)
#define K230_DAT_SYNC_B ".long 0x0ff0000f\n"
#define K230_INS_SYNC_B ".long 0x0000100f\n .long 0x0220000f\n"
#define K230_I_IALL ".long 0x0100000b\n"
#define K230_D_CIALL ".long 0x0030000b\n"
#define K230_L2_IALL ".long 0x0170000b\n"
#define K230_SYNC_IS ".long 0x01b0000b\n"
#define ASM __asm__ __volatile__
/****************************************************************************
* Private Functions
****************************************************************************/
#if !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_NUTTSBI)
/****************************************************************************
* Name: hart_has_vec_ext()
* Description: returns Non-zero if CPU has vector extension
* Name: hart_cleanup
* Description: from cleanup_before_linux() in K230 U-Boot
****************************************************************************/
int hart_has_vec_ext(void)
static void k230_hart_cleanup(void)
{
uintptr_t reg = READ_CSR(CSR_MHCR);
ASM(K230_DAT_SYNC_B);
ASM(K230_INS_SYNC_B);
ASM(K230_I_IALL); /* icache.iall */
ASM(K230_D_CIALL); /* dcache.ciall */
ASM(K230_DAT_SYNC_B);
ASM(K230_INS_SYNC_B);
reg &= ~MHCR_IE_MSK; /* icache.disable */
reg &= ~MHCR_DE_MSK; /* dcache.disable */
WRITE_CSR(CSR_MHCR, reg);
ASM(K230_L2_IALL); /* l2.iall */
ASM(K230_DAT_SYNC_B);
ASM(K230_INS_SYNC_B);
}
#endif /* !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_NUTTSBI) */
/****************************************************************************
* Public Functions
****************************************************************************/
#if !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_NUTTSBI)
/****************************************************************************
* Name: k230_hart_on_big()
* Description: returns true if running on big core
****************************************************************************/
int k230_hart_is_big(void)
{
#define MISA_VECTOR_BIT ('V'-'A')
#define MISA_VECOTR_MASK ( 1 << MISA_VECTOR_BIT )
@ -56,29 +121,95 @@ int hart_has_vec_ext(void)
/****************************************************************************
* Name: k230_hart_init()
* Description: K230 M-mode HART initialization
* Description: K230 M-mode HART setup following K230 SDK
****************************************************************************/
void k230_hart_init(void)
{
if (hart_has_vec_ext())
{
WRITE_CSR(CSR_MHCR, 0x11ff);
WRITE_CSR(CSR_MCOR, 0x70013);
WRITE_CSR(CSR_MSMPR, 0x1);
WRITE_CSR(CSR_MCCR2, 0xe0410009);
WRITE_CSR(CSR_MHINT, 0x16e30c);
}
bool big = k230_hart_is_big();
/* turn off MAEE to have standard PTE format */
k230_hart_cleanup();
WRITE_CSR(CSR_MXSTATUS, 0x438000);
WRITE_CSR(CSR_MXSTATUS, XSTATUS);
WRITE_CSR(CSR_MHCR, MHCR);
WRITE_CSR(CSR_MCOR, MCOR);
WRITE_CSR(CSR_MSMPR, MSMPR);
WRITE_CSR(CSR_MCCR2, big ? MCCR2_BIG : MCCR2);
WRITE_CSR(CSR_MHINT, big ? MHINT_BIG : MHINT);
#ifdef RISCV_PBMT
SET_CSR(CSR_MENVCFG, MENVCFG_PBMT);
#endif
}
/* Hart reset control bits */
#define CORE_DONE_BIT (1 << 12)
#define CORE_REST_BIT (1 << 0)
#define CORE_DONE_ENW (1 << (12 + 16))
#define CORE_REST_ENW (1 << (0 + 16))
#define RESET_DELAY_US 200
/****************************************************************************
* Name: k230_hart_big_stop()
* Description: stop big core
****************************************************************************/
void k230_hart_big_stop(void)
{
volatile uint32_t *rctl = (uint32_t *)K230_CPU1_RESET;
/* 0x10001000 clear DONE */
*rctl = CORE_DONE_BIT | CORE_DONE_ENW;
up_udelay(RESET_DELAY_US);
/* 0x10001 set RESET */
*rctl = CORE_REST_BIT | CORE_REST_ENW;
up_udelay(RESET_DELAY_US);
}
/****************************************************************************
* Name: k230_hart_big_boot()
* Description: start big core from given address
****************************************************************************/
void k230_hart_big_boot(uintptr_t addr)
{
volatile uint32_t *bctl = (uint32_t *)K230_CPU1_BOOTA;
volatile uint32_t *rctl = (uint32_t *)K230_CPU1_RESET;
if (k230_hart_is_big()) return;
/* learned from U-Boot baremetal and RTT sysctl_reset_cpu */
if (addr) *bctl = (uint32_t)addr;
/* 0x10001000 clear DONE */
*rctl = CORE_DONE_BIT | CORE_DONE_ENW;
up_udelay(RESET_DELAY_US);
/* 0x10001 set RESET */
*rctl = CORE_REST_BIT | CORE_REST_ENW;
up_udelay(RESET_DELAY_US);
/* 0x10000 clear RESET */
*rctl = CORE_REST_ENW;
up_udelay(RESET_DELAY_US);
}
#endif /* !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_NUTTSBI) */
#ifdef CONFIG_NUTTSBI
#ifdef CONFIG_NUTTSBI_LATE_INIT
/****************************************************************************
* Name: sbi_late_initialize runs in M-mode
* Name: sbi_late_initialize
* Description: K230 specific setup in M-mode.
****************************************************************************/
void sbi_late_initialize(void)

View File

@ -32,9 +32,13 @@
#ifndef __ASSEMBLY__
#if !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_NUTTSBI)
int hart_has_vec_ext(void); /* checks for vector extension */
void k230_hart_init(void); /* M-mode initialization */
void k230_hart_init(void); /* M-mode initialization */
int k230_hart_is_big(void); /* check if on big core */
#endif /* !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_NUTTSBI) */
void k230_hart_big_boot(uintptr_t boot); /* turn on big core w/ boot addr */
void k230_hart_big_stop(void); /* turn off big core */
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_K230_K230_HART_H */

View File

@ -40,39 +40,83 @@
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_K230_PBMT_THEAD
/* T-Head Memory Type PTE definitions */
# define _PAGE_SEC (1UL << 59) /* Security */
# define _PAGE_SHARE (1UL << 60) /* Shareable */
# define _PAGE_BUF (1UL << 61) /* Bufferable */
# define _PAGE_CACHE (1UL << 62) /* Cacheable */
# define _PAGE_SO (1UL << 63) /* Strong Order */
# define _THEAD_PMA (_PAGE_SHARE | _PAGE_BUF | _PAGE_CACHE)
# define _THEAD_IO (_PAGE_BUF | _PAGE_SO)
# define _THEAD_NC (_PAGE_SHARE | _PAGE_BUF)
# define K230_DEV_FLAGS (_THEAD_IO | MMU_IO_FLAGS)
# define K230_TXT_FLAGS (_THEAD_PMA | MMU_KTEXT_FLAGS)
# define K230_DAT_FLAGS (_THEAD_PMA | MMU_KDATA_FLAGS)
# define K230_SHM_FLAGS (_THEAD_NC | MMU_KDATA_FLAGS)
#else
/* Svpbmt Memory Type PTE definitions */
# define _PAGE_NC (1UL << 61)
# define _PAGE_IO (1UL << 62)
# define SVPBMT_PMA (0)
# define SVPBMT_IO (_PAGE_IO)
# define SVPBMT_NC (_PAGE_NC)
# define K230_DEV_FLAGS (SVPBMT_IO | MMU_IO_FLAGS)
# define K230_SHM_FLAGS (SVPBMT_NC | MMU_KDATA_FLAGS)
# define K230_TXT_FLAGS (SVPBMT_PMA | MMU_KTEXT_FLAGS)
# define K230_DAT_FLAGS (SVPBMT_PMA | MMU_KDATA_FLAGS)
#endif
/* for PTE dump purposes, covers Svpbmt or MAEE w/o bit-59 */
#define MMU_PBMT_MASK (0xful << 60)
#define MMU_PBMT_VAL(x) (((x) & MMU_PBMT_MASK) >> 60)
#define MMUFD(x) (uint16_t)(((x) & 0xff) | (MMU_PBMT_VAL(x) << 8))
/* Map the whole I/O & PLIC memory with vaddr = paddr mappings */
#define MMU_IO_BASE (0x80000000) /* KPU-Cache */
#define MMU_IO_SIZE (0x40000000) /* 1GB, till XIP start */
#define MMU_DEV_BASE (0x80400000ul) /* KPU config */
#define MMU_DEV_SIZE (0x11200000ul) /* 274MB till Hi-sys end */
#define MMU_INT_BASE (0xF00000000ul) /* PLIC base */
#define MMU_INT_SIZE (0x400000ul) /* 4MB for PLIC */
#define MMU_INT_BASE (0xF00000000ul) /* PLIC base */
#define MMU_INT_SIZE (0x400000ul) /* 4MB */
#ifdef CONFIG_RPTUN
#define MMU_SHM_BASE (uintptr_t)CONFIG_K230_RPTUN_SHM_ADDR
#define MMU_SHM_SIZE CONFIG_K230_RPTUN_SHM_SIZE
#endif
#ifndef CONFIG_ARCH_MMU_TYPE_SV39
#error "No valid MMU type defined"
#endif
/* Physical and virtual addresses to page tables (vaddr = paddr mapping)
* Note NUTTSBI kernel can live in small flash+ram regions thus needs L3
* entries
* Note NUTTSBI kernel can live in small flash+ram regions thus needs L3.
* We also assume KFLASH and KSRAM can be held by one L3 table (4MB).
*/
#define PGT_L1_PBASE (uintptr_t)&m_l1_pgtable
#define PGT_L2_PBDDR (uintptr_t)&m_l2_pgt_ddr
#define PGT_L2_PBINT (uintptr_t)&m_l2_pgt_int
#ifdef CONFIG_NUTTSBI
#define PGT_L2_PBDEV (uintptr_t)&m_l2_pgt_dev
#define PGT_L3_PBDDR (uintptr_t)&m_l3_pgt_ddr
#endif
#define PGT_L1_VBASE PGT_L1_PBASE
#define PGT_L2_VBDDR PGT_L2_PBDDR
#define PGT_L2_VBINT PGT_L2_PBINT
#ifdef CONFIG_NUTTSBI
#define PGT_L2_VBDEV PGT_L2_PBDEV
#define PGT_L3_VBDDR PGT_L3_PBDDR
#endif
#define PGT_L1_SIZE (512) /* Enough to map 512 GiB */
#define PGT_L2_SIZE (512) /* Enough to map 1 GiB */
#define PGT_L3_SIZE (512) /* Enough to map 2 MiB */
#define PGT_L1_SIZE (512) /* Enough for 512 GiB */
#define PGT_L2_SIZE (512) /* Enough for 1 GiB */
#define PGT_L3_SIZE (1024) /* Enough for 4 MiB */
/****************************************************************************
* Private Types
@ -82,30 +126,25 @@
* Private Data
****************************************************************************/
/* Kernel mappings simply here, mapping is vaddr=paddr */
/* Kernel mapping use simple identical mapping (i.e. vaddr==paddr). */
static size_t m_l1_pgtable[PGT_L1_SIZE] locate_data(".pgtables");
static size_t m_l2_pgt_ddr[PGT_L2_SIZE] locate_data(".pgtables");
static size_t m_l2_pgt_dev[PGT_L2_SIZE] locate_data(".pgtables");
static size_t m_l2_pgt_int[PGT_L2_SIZE] locate_data(".pgtables");
#ifdef CONFIG_NUTTSBI
static size_t m_l2_pgt_ddr[PGT_L2_SIZE] locate_data(".pgtables");
static size_t m_l3_pgt_ddr[PGT_L3_SIZE] locate_data(".pgtables");
#endif
/* Kernel mappings (L1 base) required by riscv_addrenv */
uintptr_t g_kernel_mappings = PGT_L1_VBASE;
uintptr_t g_kernel_pgt_pbase = PGT_L1_PBASE;
uintptr_t g_kernel_mappings = PGT_L1_VBASE;
uintptr_t g_kernel_pgt_pbase = PGT_L1_PBASE;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: dump_pgtable
*
* Description:
* Dump page tables to console, mainly for debugging purposes.
*
* Name: dump_pgtable dump one pagetable
****************************************************************************/
static void dump_pgtable(const size_t * pgt, uint32_t len, const char * name)
@ -116,8 +155,8 @@ static void dump_pgtable(const size_t * pgt, uint32_t len, const char * name)
uintptr_t pte = (uintptr_t)pgt[i];
if (pte & PTE_VALID)
{
minfo("#%03d paddr:%09lx flags:%02x %s\n", i,
mmu_pte_to_paddr(pte), (unsigned)(pte & 0xff),
minfo("#%03d paddr:%09lx flags:%03x %s\n", i,
mmu_pte_to_paddr(pte), MMUFD(pte),
(pte & PTE_LEAF_MASK)? "" : ">>>");
}
}
@ -138,68 +177,63 @@ static void dump_pgtable(const size_t * pgt, uint32_t len, const char * name)
void k230_kernel_mappings(void)
{
/* 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
* addresses and so forth. M-mode does not perform translations anyhow, so
* this mapping is quite simple to do
*/
/* Map I/O region in L2 page table. */
/* Map I/O region in L1 page table. */
minfo("\nflags: dev=%03x shm=%03x dat=%03x txt=%03x\n",
MMUFD(K230_DEV_FLAGS | PTE_VALID), MMUFD(K230_SHM_FLAGS | PTE_VALID),
MMUFD(K230_DAT_FLAGS | PTE_VALID), MMUFD(K230_TXT_FLAGS | PTE_VALID));
minfo("map L1 I/O regions(%dGB)\n", MMU_IO_SIZE >> 30);
mmu_ln_map_region(1, PGT_L1_VBASE, MMU_IO_BASE, MMU_IO_BASE,
MMU_IO_SIZE, MMU_IO_FLAGS);
minfo("map DEV L2(%ldMB)\n", MMU_DEV_SIZE >> 20);
mmu_ln_map_region(2, PGT_L2_VBDEV, MMU_DEV_BASE, MMU_DEV_BASE,
MMU_DEV_SIZE, K230_DEV_FLAGS);
/* Map INT region using L2 page table */
minfo("map L2 INT regions(%ldMB)\n", MMU_INT_SIZE >> 20);
minfo("map INT L2(%ldMB)\n", MMU_INT_SIZE >> 20);
mmu_ln_map_region(2, PGT_L2_VBINT, MMU_INT_BASE, MMU_INT_BASE,
MMU_INT_SIZE, MMU_IO_FLAGS);
MMU_INT_SIZE, K230_DEV_FLAGS);
/* Map kernel text and data using L2 pages */
/* Map kernel area use L3 */
minfo("map kernel text(%ldMB)\n", KFLASH_SIZE >> 20);
mmu_ln_map_region(2, PGT_L2_VBDDR, KFLASH_START, KFLASH_START,
KFLASH_SIZE, MMU_KTEXT_FLAGS);
#ifdef CONFIG_NUTTSBI
minfo("map kernel L2/L3(%ldKB)\n", (KFLASH_SIZE + KSRAM_SIZE) >> 10);
mmu_ln_map_region(3, PGT_L3_VBDDR, KFLASH_START, KFLASH_START,
KFLASH_SIZE, MMU_KTEXT_FLAGS);
mmu_ln_setentry(2, PGT_L2_VBDDR, PGT_L3_PBDDR, KFLASH_START, 0);
#endif
minfo("map kernel data(%ldMB)\n", KSRAM_SIZE >> 20);
mmu_ln_map_region(2, PGT_L2_VBDDR, KSRAM_START, KSRAM_START,
KSRAM_SIZE, MMU_KDATA_FLAGS);
#ifdef CONFIG_NUTTSBI
KFLASH_SIZE, K230_TXT_FLAGS);
mmu_ln_map_region(3, PGT_L3_VBDDR, KSRAM_START, KSRAM_START,
KSRAM_SIZE, MMU_KDATA_FLAGS);
mmu_ln_setentry(2, PGT_L2_VBDDR, PGT_L3_PBDDR, KSRAM_START, 0);
#endif
KSRAM_SIZE, K230_DAT_FLAGS);
/* Map the page pool */
minfo("map L2 pages pool(%ldMB)\n", PGPOOL_SIZE >> 20);
minfo("map pgpool L2(%ldMB)\n", PGPOOL_SIZE >> 20);
mmu_ln_map_region(2, PGT_L2_VBDDR, PGPOOL_START, PGPOOL_START,
PGPOOL_SIZE, MMU_KDATA_FLAGS);
PGPOOL_SIZE, K230_DAT_FLAGS);
/* Connect the L1 and L2 page tables */
#ifdef CONFIG_RPTUN
uintptr_t base;
minfo("connect L1 and L2 DDR pgtables\n");
/* map shared memory, 2MB aligned in either DDR or DEV/SRAM zone */
minfo("map shmem L2(%dKB)\n", (MMU_SHM_SIZE) >> 10);
base = (CONFIG_K230_RPTUN_SHM_ADDR >= 0x80000000) ? PGT_L2_VBDEV
: PGT_L2_VBDDR;
mmu_ln_map_region(2, base, MMU_SHM_BASE, MMU_SHM_BASE,
MMU_SHM_SIZE, K230_SHM_FLAGS);
#endif
/* Connect page tables, two tables can only connect once. */
minfo("connect L1, L2 and L3\n");
mmu_ln_setentry(1, PGT_L1_VBASE, PGT_L2_PBDDR, KFLASH_START, 0);
/* Connect the L1 and L2 page tables for INT regions */
minfo("connect L1 and L2 INT pgtables\n");
mmu_ln_setentry(1, PGT_L1_VBASE, PGT_L2_PBDEV, MMU_DEV_BASE, 0);
mmu_ln_setentry(1, PGT_L1_VBASE, PGT_L2_PBINT, MMU_INT_BASE, 0);
mmu_ln_setentry(2, PGT_L2_VBDDR, PGT_L3_PBDDR, KFLASH_START, 0);
/* dump page tables */
dump_pgtable(m_l1_pgtable, PGT_L1_SIZE, "L1");
dump_pgtable(m_l2_pgt_ddr, PGT_L2_SIZE, "L2_DDR");
dump_pgtable(m_l2_pgt_dev, PGT_L2_SIZE, "L2_DEV");
dump_pgtable(m_l2_pgt_int, PGT_L2_SIZE, "L2_INT");
#ifdef CONFIG_NUTTSBI
dump_pgtable(m_l2_pgt_ddr, PGT_L2_SIZE, "L2_DDR");
dump_pgtable(m_l3_pgt_ddr, PGT_L3_SIZE, "L3_DDR");
#endif
}
/****************************************************************************
@ -217,8 +251,6 @@ void k230_mm_init(void)
k230_kernel_mappings();
/* Enable MMU (note: system in S-mode) */
minfo("mmu_enable: satp=%lx\n", g_kernel_pgt_pbase);
mmu_enable(g_kernel_pgt_pbase, 0);
}

View File

@ -0,0 +1,412 @@
/****************************************************************************
* arch/risc-v/src/k230/k230_rptun.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 <assert.h>
#include <debug.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/kthread.h>
#include <nuttx/semaphore.h>
#include <nuttx/spi/spi.h>
#include <nuttx/wqueue.h>
#include <nuttx/rptun/openamp.h>
#include <nuttx/rptun/rptun.h>
#include <nuttx/drivers/addrenv.h>
#include <nuttx/list.h>
#include <arch/barriers.h>
#include <arch/board/board.h>
#include "hardware/k230_memorymap.h"
#include "k230_hart.h"
#include "riscv_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_DEBUG_ERROR
# define rperr _err
# define rpwarn _warn
# define rpinfo _info
#else
# define rperr(x...)
# define rpwarn(x...)
# define rpinfo(x...)
#endif
/* Vring config parameters taken from nrf53_rptun */
#define VRINGS 2 /* Number of vrings */
#define VRING_ALIGN 8 /* Vring alignment */
#define VRING_NR 8 /* Number of descriptors */
#define VRING_SIZE 512 /* Size of one descriptor */
/* The RPMSG default channel used with only one RPMSG channel */
#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Use polling now as IPI is not ready initially.
****************************************************************************/
struct k230_rptun_shmem_s
{
volatile uintptr_t base;
#ifndef CONFIG_K230_RPTUN_IPI
volatile uint32_t seq_rmt; /* seqno for remote to watch */
volatile uint32_t seq_mst; /* seqno for master to watch */
#endif
struct rptun_rsc_s rsc;
};
struct k230_rptun_dev_s
{
struct rptun_dev_s rptun;
rptun_callback_t callback;
void *arg;
bool master;
struct k230_rptun_shmem_s *shmem;
struct simple_addrenv_s addrenv[VRINGS];
char peername[RPMSG_NAME_SIZE + 1];
#ifndef CONFIG_K230_RPTUN_IPI
volatile uint32_t seq;
struct work_s work;
#endif
};
#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static const char *rp_get_cpuname(struct rptun_dev_s *dev);
static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
static bool rp_is_autostart(struct rptun_dev_s *dev);
static bool rp_is_master(struct rptun_dev_s *dev);
static int rp_start(struct rptun_dev_s *dev);
static int rp_stop(struct rptun_dev_s *dev);
static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
#ifndef CONFIG_K230_RPTUN_IPI
static void k230_rptun_work(void *arg);
#endif /* CONFIG_K230_RPTUN_IPI */
/****************************************************************************
* Private Data
****************************************************************************/
static const struct rptun_ops_s g_k230_rptun_ops =
{
.get_cpuname = rp_get_cpuname,
.get_resource = rp_get_resource,
.is_autostart = rp_is_autostart,
.is_master = rp_is_master,
.start = rp_start,
.stop = rp_stop,
.notify = rp_notify,
.register_callback = rp_set_callback,
};
#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
static struct k230_rptun_dev_s g_rptun_dev;
#ifdef CONFIG_K230_RPTUN_IPI
static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: rp_get_cpuname
****************************************************************************/
static const char *rp_get_cpuname(struct rptun_dev_s *dev)
{
struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
return priv->peername;
}
/****************************************************************************
* Name: rp_get_resource
****************************************************************************/
static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
{
struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
struct rptun_rsc_s *rsc;
if (priv->shmem != NULL)
{
return &priv->shmem->rsc;
}
priv->shmem = SHMEM;
if (priv->master)
{
/* Perform initial setup */
rsc = &priv->shmem->rsc;
rsc->rsc_tbl_hdr.ver = 1;
rsc->rsc_tbl_hdr.num = 1;
rsc->rsc_tbl_hdr.reserved[0] = 0;
rsc->rsc_tbl_hdr.reserved[1] = 0;
rsc->offset[0] = offsetof(struct rptun_rsc_s,
rpmsg_vdev);
rsc->rpmsg_vdev.type = RSC_VDEV;
rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
| 1 << VIRTIO_RPMSG_F_ACK
| 1 << VIRTIO_RPMSG_F_BUFSZ;
rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
rsc->rpmsg_vdev.num_of_vrings = VRINGS;
rsc->rpmsg_vring0.align = VRING_ALIGN;
rsc->rpmsg_vring0.num = VRING_NR;
rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
rsc->rpmsg_vring1.align = VRING_ALIGN;
rsc->rpmsg_vring1.num = VRING_NR;
rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
rsc->config.r2h_buf_size = VRING_SIZE;
rsc->config.h2r_buf_size = VRING_SIZE;
priv->shmem->base = (uintptr_t)priv->shmem;
rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
}
else
{
/* TODO: use IPI later, polling now. */
rpinfo("wait for shmem %p...\n", priv->shmem);
while (priv->shmem->base == 0)
{
nxsig_usleep(100);
}
rpinfo("ready to go!\n");
}
return &priv->shmem->rsc;
}
/****************************************************************************
* Name: rp_is_autostart
****************************************************************************/
static bool rp_is_autostart(struct rptun_dev_s *dev)
{
return true;
}
/****************************************************************************
* Name: rp_is_master
****************************************************************************/
static bool rp_is_master(struct rptun_dev_s *dev)
{
struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
return priv->master;
}
/****************************************************************************
* Name: rp_start
****************************************************************************/
static int rp_start(struct rptun_dev_s *dev)
{
return 0;
}
/****************************************************************************
* Name: rp_stop
****************************************************************************/
static int rp_stop(struct rptun_dev_s *dev)
{
return 0;
}
/****************************************************************************
* Name: rp_notify
****************************************************************************/
static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
{
#ifdef CONFIG_K230_RPTUN_IPI
k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
#else
struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
if (priv->master)
{
priv->shmem->seq_rmt++;
}
else
{
priv->shmem->seq_mst++;
}
#endif /* CONFIG_K230_RPTUN_IPI */
return 0;
}
/****************************************************************************
* Name: rp_reg_cb
****************************************************************************/
static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
void *arg)
{
struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
priv->callback = cb;
priv->arg = arg;
rpinfo("%p, arg:%p\n", cb, arg);
return 0;
}
#ifndef CONFIG_K230_RPTUN_IPI
static void k230_rptun_work(void *arg)
{
struct k230_rptun_dev_s *dev = arg;
bool should_notify = false;
if (dev->shmem != NULL)
{
if (dev->master && dev->seq != dev->shmem->seq_mst)
{
dev->seq = dev->shmem->seq_mst;
should_notify = true;
}
else if (!dev->master && dev->seq != dev->shmem->seq_rmt)
{
dev->seq = dev->shmem->seq_rmt;
should_notify = true;
}
if (should_notify && dev->callback != NULL)
{
dev->callback(dev->arg, RPTUN_NOTIFY_ALL);
}
}
work_queue(HPWORK, &dev->work, k230_rptun_work, dev,
CONFIG_K230_RPTUN_WORK_DELAY);
}
#endif /* !CONFIG_K230_RPTUN_IPI */
/****************************************************************************
* Public Functions
****************************************************************************/
int k230_rptun_init(const char *peername)
{
struct k230_rptun_dev_s *dev = &g_rptun_dev;
int ret = OK;
#ifdef CONFIG_K230_RPTUN_MASTER
/* master is responsible for initializing shmem */
memset((void *)SHMEM, 0, SHMEM_SIZE);
rpinfo("\ncleared %d @ %p\n", SHMEM_SIZE, SHMEM);
dev->master = true;
#else
dev->master = false;
#endif
#ifdef CONFIG_K230_RPTUN_IPI
k230_ipi_init();
#ifdef CONFIG_K230_RPTUN_MASTER
k230_rptun_ipi_master(dev);
#else
k230_rptun_ipi_remote(dev);
#endif
#endif /* CONFIG_K230_RPTUN_IPI */
/* Configure device */
dev->rptun.ops = &g_k230_rptun_ops;
strncpy(dev->peername, peername, RPMSG_NAME_SIZE);
ret = rptun_initialize(&dev->rptun);
if (ret < 0)
{
rperr("ERROR: rptun_initialize failed %d!\n", ret);
goto errout;
}
#ifdef CONFIG_K230_RPTUN_IPI
/* Create rptun RX thread */
ret = kthread_create("k230-rptun", CONFIG_RPTUN_PRIORITY,
CONFIG_RPTUN_STACKSIZE, k230_rptun_thread, NULL);
#else
/* Kick off work */
ret = work_queue(HPWORK, &dev->work, k230_rptun_work, dev, 0);
#endif
if (ret < 0)
{
rperr("ERROR: kthread_create or work_queue failed %d\n", ret);
}
errout:
return ret;
}

View File

@ -0,0 +1,63 @@
/****************************************************************************
* arch/risc-v/src/k230/k230_rptun.h
*
* 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.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_K230_K230_RPTUN_H
#define __ARCH_RISCV_SRC_K230_K230_RPTUN_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: k230_rptun_init
*
* Description: initializes K230 RPTUN device.
*
* Returns: OK on success, or negated number on error
*
****************************************************************************/
int k230_rptun_init(const char *peername);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_K230_K230_RPTUN_H */

View File

@ -28,6 +28,7 @@
#include <nuttx/init.h>
#include <nuttx/arch.h>
#include <nuttx/serial/uart_16550.h>
#include <nuttx/serial/uart_rpmsg.h>
#include <arch/board/board.h>
#include "riscv_internal.h"
@ -63,9 +64,7 @@ static void k230_clear_bss(void)
{
uint32_t *dest;
/* Clear .bss. We'll do this inline (vs. calling memset) just to be
* certain that there are no issues with the state of global variables.
*/
/* Doing this inline just to be sure on the state of global variables. */
for (dest = (uint32_t *)_sbss; dest < (uint32_t *)_ebss; )
{
@ -75,17 +74,17 @@ static void k230_clear_bss(void)
#ifndef CONFIG_BUILD_KERNEL
/****************************************************************************
* Name: k230_copy_initialized
* Name: k230_copy_init_data
****************************************************************************/
static void k230_copy_initialized(void)
static void k230_copy_init_data(void)
{
const uint32_t *src;
uint32_t *dest;
/* Move the initialized data section from his temporary holding spot in
* FLASH into the correct place in SRAM. The correct place in SRAM is
* give by _sdata and _edata. The temporary location is in FLASH at the
/* Move the initialized data from their temporary holding spot at FLASH
* into the correct place in SRAM. The correct place in SRAM is given
* by _sdata and _edata. The temporary location is in FLASH at the
* end of all of the other read-only data (.text, .rodata) at _eronly.
*/
@ -125,7 +124,7 @@ void k230_start(int mhartid, const char *dtb)
#ifdef CONFIG_BUILD_KERNEL
riscv_percpu_add_hart(mhartid);
#else
k230_copy_initialized();
k230_copy_init_data();
#endif
}
@ -184,10 +183,23 @@ cpux:
void riscv_earlyserialinit(void)
{
#ifdef CONFIG_16550_UART
u16550_earlyserialinit();
#endif
}
void riscv_serialinit(void)
{
#ifdef CONFIG_16550_UART
u16550_serialinit();
#endif
}
#ifdef CONFIG_RPMSG_UART_CONSOLE
int up_putc(int ch)
{
/* place holder for now */
return ch;
}
#endif

View File

@ -0,0 +1,109 @@
#
# 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_REGWIDTH=32
CONFIG_16550_SERIAL_DISABLE_REORDERING=y
CONFIG_16550_SUPRESS_CONFIG=y
CONFIG_16550_UART0=y
CONFIG_16550_UART0_BASE=0x91400000
CONFIG_16550_UART0_CLOCK=50000000
CONFIG_16550_UART0_IRQ=41
CONFIG_16550_UART0_SERIAL_CONSOLE=y
CONFIG_16550_UART=y
CONFIG_16550_WAIT_LCR=y
CONFIG_ARCH="risc-v"
CONFIG_ARCH_ADDRENV=y
CONFIG_ARCH_BOARD="canmv230"
CONFIG_ARCH_BOARD_K230_CANMV=y
CONFIG_ARCH_CHIP="k230"
CONFIG_ARCH_CHIP_K230=y
CONFIG_ARCH_DATA_NPAGES=128
CONFIG_ARCH_DATA_VBASE=0xC0100000
CONFIG_ARCH_HEAP_NPAGES=128
CONFIG_ARCH_HEAP_VBASE=0xC0200000
CONFIG_ARCH_INTERRUPTSTACK=3072
CONFIG_ARCH_KERNEL_STACKSIZE=3072
CONFIG_ARCH_LAZYFPU=y
CONFIG_ARCH_PGPOOL_MAPPING=y
CONFIG_ARCH_PGPOOL_PBASE=0x8200000
CONFIG_ARCH_PGPOOL_SIZE=14680064
CONFIG_ARCH_PGPOOL_VBASE=0x8200000
CONFIG_ARCH_RISCV=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_BINFMT_ELF_EXECUTABLE=y
CONFIG_BLK_RPMSG_SERVER=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=6366
CONFIG_BUILD_KERNEL=y
CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEV_RPMSG_SERVER=y
CONFIG_DEV_SIMPLE_ADDRENV=y
CONFIG_DEV_ZERO=y
CONFIG_ELF=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_FS_PROCFS=y
CONFIG_FS_ROMFS=y
CONFIG_FS_RPMSGFS_SERVER=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INIT_FILEPATH="/system/bin/init"
CONFIG_INIT_MOUNT=y
CONFIG_INIT_MOUNT_FLAGS=0x1
CONFIG_INIT_MOUNT_TARGET="/system/bin"
CONFIG_INIT_STACKSIZE=3072
CONFIG_K230_RPTUN_MASTER=y
CONFIG_LIBC_ENVPATH=y
CONFIG_LIBC_EXECFUNCS=y
CONFIG_LIBC_HOSTNAME="master"
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_LIBM=y
CONFIG_MEMSET_64BIT=y
CONFIG_MEMSET_OPTSPEED=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_PROMPT_STRING="master> "
CONFIG_NSH_READLINE=y
CONFIG_NUTTSBI=y
CONFIG_NUTTSBI_MTIMECMP_BASE=0xf04004000
CONFIG_NUTTSBI_MTIME_BASE=0xf0400bff8
CONFIG_PATH_INITIAL="/system/bin"
CONFIG_RAM_SIZE=16777216
CONFIG_RAM_START=0x8000000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RPMSG_PING=y
CONFIG_RPMSG_UART=y
CONFIG_RPTUN=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_WAITPID=y
CONFIG_SERIAL_UART_ARCH_MMIO=y
CONFIG_STACK_COLORATION=y
CONFIG_STANDARD_SERIAL=y
CONFIG_START_DAY=10
CONFIG_START_MONTH=2
CONFIG_START_YEAR=2024
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSLOG_RPMSG_SERVER=y
CONFIG_SYSTEM_CUTERM=y
CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE="/dev/ttyRpmsg"
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_NSH_PROGNAME="init"
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_USEC_PER_TICK=1000

View File

@ -72,7 +72,6 @@ CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_FILE_APPS=y
CONFIG_NSH_READLINE=y
CONFIG_NUTTSBI=y
CONFIG_NUTTSBI_LATE_INIT=y
CONFIG_NUTTSBI_MTIMECMP_BASE=0xf04004000
CONFIG_NUTTSBI_MTIME_BASE=0xf0400bff8
CONFIG_PATH_INITIAL="/system/bin"

View File

@ -0,0 +1,89 @@
#
# 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_ARCH="risc-v"
CONFIG_ARCH_ADDRENV=y
CONFIG_ARCH_BOARD="canmv230"
CONFIG_ARCH_BOARD_K230_CANMV=y
CONFIG_ARCH_CHIP="k230"
CONFIG_ARCH_CHIP_K230=y
CONFIG_ARCH_DATA_NPAGES=128
CONFIG_ARCH_DATA_VBASE=0xC0100000
CONFIG_ARCH_HEAP_NPAGES=128
CONFIG_ARCH_HEAP_VBASE=0xC0200000
CONFIG_ARCH_INTERRUPTSTACK=3072
CONFIG_ARCH_KERNEL_STACKSIZE=3072
CONFIG_ARCH_LAZYFPU=y
CONFIG_ARCH_PGPOOL_MAPPING=y
CONFIG_ARCH_PGPOOL_PBASE=0x7200000
CONFIG_ARCH_PGPOOL_SIZE=14680064
CONFIG_ARCH_PGPOOL_VBASE=0x7200000
CONFIG_ARCH_RISCV=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_BINFMT_ELF_EXECUTABLE=y
CONFIG_BLK_RPMSG=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=6366
CONFIG_BUILD_KERNEL=y
CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEV_SIMPLE_ADDRENV=y
CONFIG_DEV_ZERO=y
CONFIG_ELF=y
CONFIG_FS_PROCFS=y
CONFIG_FS_ROMFS=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INIT_FILEPATH="/system/bin/init"
CONFIG_INIT_MOUNT=y
CONFIG_INIT_MOUNT_FLAGS=0x1
CONFIG_INIT_MOUNT_TARGET="/system/bin"
CONFIG_INIT_STACKSIZE=3072
CONFIG_LIBC_ENVPATH=y
CONFIG_LIBC_EXECFUNCS=y
CONFIG_LIBC_HOSTNAME="remote"
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_LIBM=y
CONFIG_MEMSET_64BIT=y
CONFIG_MEMSET_OPTSPEED=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_PROMPT_STRING="remote> "
CONFIG_NSH_READLINE=y
CONFIG_NUTTSBI=y
CONFIG_NUTTSBI_MTIMECMP_BASE=0xf04004000
CONFIG_NUTTSBI_MTIME_BASE=0xf0400bff8
CONFIG_PATH_INITIAL="/system/bin"
CONFIG_RAM_SIZE=16777216
CONFIG_RAM_START=0x7000000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RPMSG_UART=y
CONFIG_RPMSG_UART_CONSOLE=y
CONFIG_RPTUN=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_WAITPID=y
CONFIG_STACK_COLORATION=y
CONFIG_STANDARD_SERIAL=y
CONFIG_START_DAY=10
CONFIG_START_MONTH=2
CONFIG_START_YEAR=2024
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_NSH_PROGNAME="init"
CONFIG_TESTING_GETPRIME=y
CONFIG_USEC_PER_TICK=1000

View File

@ -25,7 +25,11 @@ include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs
ifeq ($(CONFIG_ARCH_CHIP_K230),y)
ifeq ($(CONFIG_BUILD_KERNEL),y)
ifeq ($(CONFIG_NUTTSBI),y)
LDSCRIPT = ld-nuttsbi.script
ifeq ($(CONFIG_RPTUN),y)
LDSCRIPT = ld-rptun.script
else
LDSCRIPT = ld-nuttsbi.script
endif
else
LDSCRIPT = ld-kernel.script
endif

View File

@ -0,0 +1,170 @@
/****************************************************************************
* boards/risc-v/k230/canmv230/scripts/ld-rptun.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.
*
****************************************************************************/
#include <nuttx/config.h>
/* Enlage kernel data size or pgpool config to reduce nuttx.bin size */
#define KSRAM_SIZE (1536*1024)
/* We only respect RAM and PGPOOL configs for simplicity */
#define PGRAM_ADDR (CONFIG_ARCH_PGPOOL_PBASE)
#define PGRAM_SIZE (CONFIG_ARCH_PGPOOL_SIZE)
#define PGRAM_END (PGRAM_ADDR + PGRAM_SIZE)
#define CFRAM_END (CONFIG_RAM_START + CONFIG_RAM_SIZE)
#if (PGRAM_ADDR < CONFIG_RAM_START) || (PGRAM_END > CFRAM_END)
#error invalid RAM or PGPOOL configuration!
#endif
#if (PGRAM_END < CFRAM_END)
# warn are we wasting CFRAM_END-PGRAM_END bytes?
#endif
#define KTEXT_ADDR (CONFIG_RAM_START)
#define KRAM_TOTAL (PGRAM_ADDR - KTEXT_ADDR) /* ignore space after pgpool */
#define KTEXT_SIZE (KRAM_TOTAL-KSRAM_SIZE)
#define KSRAM_ADDR (KTEXT_ADDR + KTEXT_SIZE)
MEMORY
{
kflash (rx) : ORIGIN = KTEXT_ADDR, LENGTH = KTEXT_SIZE /* w/ cache */
ksram (rwx) : ORIGIN = KSRAM_ADDR, LENGTH = KSRAM_SIZE /* w/ cache */
pgram (rwx) : ORIGIN = PGRAM_ADDR, LENGTH = PGRAM_SIZE /* w/ cache */
}
OUTPUT_ARCH("riscv")
/* Provide the kernel boundaries, used in board memory map */
__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
{
. = KTEXT_ADDR;
.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 = . ;
}
.bss :
{
_sbss = . ;
*(.bss)
*(.bss.*)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.b*)
*(COMMON)
_ebss = . ;
} > ksram
/* Page tables here, align to 4K boundary */
.pgtables (NOLOAD) : ALIGN(0x1000) {
*(.pgtables)
. = ALIGN(4);
} > 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) }
}

View File

@ -36,6 +36,14 @@
#include <sys/boardctl.h>
#include <arch/board/board_memorymap.h>
#ifdef CONFIG_RPMSG_UART
# include <nuttx/serial/uart_rpmsg.h>
#endif
#ifdef CONFIG_RPTUN
# include "k230_rptun.h"
#endif
#ifdef CONFIG_BUILD_KERNEL
#include "romfs.h"
#endif
@ -57,6 +65,33 @@
* Public Functions
****************************************************************************/
int board_reset(int status)
{
_alert("status=%d, halt now.\n", status);
while (1)
{
asm volatile("wfi");
}
return 0;
}
#ifdef CONFIG_RPMSG_UART
/****************************************************************************
* Name: rpmsg_serialinit
* Description: initialize /dev/ttyRpmsg device
****************************************************************************/
void rpmsg_serialinit(void)
{
#ifdef CONFIG_K230_RPTUN_MASTER
uart_rpmsg_init("remote", "Rpmsg", 4096, false);
#else
uart_rpmsg_init("master", "Rpmsg", 4096, true);
#endif
}
#endif
/****************************************************************************
* Name: board_app_initialize
*
@ -142,4 +177,12 @@ void board_late_initialize(void)
mount(NULL, "/proc", "procfs", 0, NULL);
#endif
#ifdef CONFIG_RPTUN
# ifdef CONFIG_K230_RPTUN_MASTER
k230_rptun_init("remote");
# else
k230_rptun_init("master");
# endif
#endif
}