You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2019/12/31 14:54:43 UTC

[incubator-nuttx] branch dev updated: feature k210 (#16)

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/dev by this push:
     new fbc046e  feature k210 (#16)
fbc046e is described below

commit fbc046e97d212471e6dad26b3324b052c573e247
Author: Masayuki Ishikawa <ma...@gmail.com>
AuthorDate: Tue Dec 31 23:54:35 2019 +0900

    feature k210 (#16)
    
    * arch: risc-v: Add support for __LP64__ to types.h
    * arch: risc-v: Add support for RV64GC to common files
    * arch: risc-v: Add support for Kendryte K210 processor (RV64GC)
    * boards: risk-v: Add support for Sipeed Maix Bit with K210
    * tools: Add support for Kendryte K210 processor
---
 arch/risc-v/Kconfig                                |  20 +-
 arch/risc-v/include/irq.h                          |   4 +
 .../up_modifyreg32.c => include/k210/chip.h}       |  49 +-
 arch/risc-v/include/{syscall.h => k210/irq.h}      |  94 ++-
 arch/risc-v/include/limits.h                       |  16 +
 arch/risc-v/include/rv64gc/irq.h                   | 352 ++++++++++
 arch/risc-v/include/rv64gc/syscall.h               | 209 ++++++
 arch/risc-v/include/syscall.h                      |   4 +
 arch/risc-v/include/types.h                        |   7 +
 arch/risc-v/src/Makefile                           |   2 +
 arch/risc-v/src/common/up_arch.h                   |   2 +-
 arch/risc-v/src/common/up_createstack.c            |   6 +-
 arch/risc-v/src/common/up_internal.h               |  14 +
 arch/risc-v/src/common/up_modifyreg32.c            |   2 +-
 arch/risc-v/src/common/up_stackframe.c             |   6 +-
 arch/risc-v/src/common/up_usestack.c               |   8 +-
 arch/risc-v/src/k210/Kconfig                       |  28 +
 arch/risc-v/src/k210/Make.defs                     |  62 ++
 .../src/{common/up_modifyreg32.c => k210/chip.h}   |  44 +-
 .../irq.h => src/k210/hardware/k210_clint.h}       |  43 +-
 .../irq.h => src/k210/hardware/k210_memorymap.h}   |  45 +-
 .../irq.h => src/k210/hardware/k210_plic.h}        |  47 +-
 .../irq.h => src/k210/hardware/k210_uart.h}        |  62 +-
 .../src/{common/up_modifyreg32.c => k210/k210.h}   |  45 +-
 .../up_modifyreg32.c => k210/k210_allocateheap.c}  |  35 +-
 .../up_modifyreg32.c => k210/k210_clockconfig.c}   |  39 +-
 .../syscall.h => src/k210/k210_clockconfig.h}      |  47 +-
 .../up_modifyreg32.c => k210/k210_config.h}        |  54 +-
 arch/risc-v/src/k210/k210_head.S                   | 213 ++++++
 .../{common/up_modifyreg32.c => k210/k210_idle.c}  |  47 +-
 arch/risc-v/src/k210/k210_irq.c                    | 272 ++++++++
 .../irq.h => src/k210/k210_irq_dispatch.c}         |  93 ++-
 arch/risc-v/src/k210/k210_lowputc.c                | 140 ++++
 .../up_modifyreg32.c => k210/k210_lowputc.h}       |  52 +-
 .../{include/irq.h => src/k210/k210_memorymap.h}   |  47 +-
 arch/risc-v/src/k210/k210_serial.c                 | 745 +++++++++++++++++++++
 .../{include/syscall.h => src/k210/k210_start.c}   | 116 +++-
 .../syscall.h => src/k210/k210_timerisr.c}         | 118 +++-
 .../up_modifyreg32.c => k210/k210_vectors.S}       |  52 +-
 arch/risc-v/src/k210/up_schedulesigaction.c        | 209 ++++++
 arch/risc-v/src/rv64gc/Kconfig                     |  29 +
 arch/risc-v/src/rv64gc/Toolchain.defs              |  93 +++
 arch/risc-v/src/rv64gc/up_assert.c                 | 411 ++++++++++++
 arch/risc-v/src/rv64gc/up_blocktask.c              | 179 +++++
 .../syscall.h => src/rv64gc/up_copystate.c}        |  57 +-
 .../up_modifyreg32.c => rv64gc/up_initialstate.c}  |  80 ++-
 arch/risc-v/src/rv64gc/up_releasepending.c         | 149 +++++
 arch/risc-v/src/rv64gc/up_reprioritizertr.c        | 203 ++++++
 arch/risc-v/src/rv64gc/up_sigdeliver.c             | 146 ++++
 arch/risc-v/src/rv64gc/up_swint.c                  | 286 ++++++++
 .../{include/syscall.h => src/rv64gc/up_syscall.S} |  93 ++-
 arch/risc-v/src/rv64gc/up_unblocktask.c            | 163 +++++
 boards/Kconfig                                     |  11 +
 boards/risc-v/k210/drivers/Kconfig                 |   4 +
 boards/risc-v/k210/maix-bit/Kconfig                |   8 +
 boards/risc-v/k210/maix-bit/README.txt             |  35 +
 boards/risc-v/k210/maix-bit/configs/nsh/defconfig  |  65 ++
 .../risc-v/k210/maix-bit/include/board.h           |  40 +-
 boards/risc-v/k210/maix-bit/scripts/Make.defs      | 112 ++++
 boards/risc-v/k210/maix-bit/scripts/ld.script      | 125 ++++
 boards/risc-v/k210/maix-bit/src/Makefile           |  44 ++
 .../risc-v/k210/maix-bit/src/k210_appinit.c        |  55 +-
 .../risc-v/k210/maix-bit/src/k210_boot.c           |  36 +-
 .../risc-v/k210/maix-bit/src/k210_bringup.c        |  46 +-
 .../risc-v/k210/maix-bit/src/maix-bit.h            |  42 +-
 tools/configure.sh                                 |   2 +-
 tools/refresh.sh                                   |   2 +-
 tools/testbuild.sh                                 |   2 +-
 68 files changed, 5178 insertions(+), 790 deletions(-)

diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig
index 80753f1..18b859b 100644
--- a/arch/risc-v/Kconfig
+++ b/arch/risc-v/Kconfig
@@ -16,6 +16,12 @@ config ARCH_CHIP_FE310
 	---help---
 		SiFive FE310 processor (E31 RISC-V Core with MAC extensions).
 
+config ARCH_CHIP_K210
+	bool "Kendryte K210"
+	select ARCH_RV64GC
+	---help---
+		Kendryte K210 processor (RISC-V 64bit core with GC extensions)
+
 config ARCH_CHIP_NR5
 	bool "NEXT NanoRisc5"
 	select ARCH_RV32IM
@@ -39,13 +45,19 @@ config ARCH_RV32IM
 	bool
 	default n
 
+config ARCH_RV64GC
+	bool
+	default n
+
 config ARCH_FAMILY
 	string
-	default "rv32im"	if ARCH_RM32IM
+	default "rv32im"	if ARCH_RV32IM
+	default "rv64gc"	if ARCH_RV64GC
 
 config ARCH_CHIP
 	string
 	default "fe310"		if ARCH_CHIP_FE310
+	default "k210"		if ARCH_CHIP_K210
 	default "nr5m100"	if ARCH_CHIP_NR5
 	default "gap8"		if ARCH_CHIP_GAP8
 
@@ -62,9 +74,15 @@ config NR5_MPU
 if ARCH_RV32IM
 source arch/risc-v/src/rv32im/Kconfig
 endif
+if ARCH_RV64GC
+source arch/risc-v/src/rv64gc/Kconfig
+endif
 if ARCH_CHIP_FE310
 source arch/risc-v/src/fe310/Kconfig
 endif
+if ARCH_CHIP_K210
+source arch/risc-v/src/k210/Kconfig
+endif
 if ARCH_CHIP_NR5
 source arch/risc-v/src/nr5m100/Kconfig
 endif
diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/include/irq.h
index 338b9a1..4ff217e 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/include/irq.h
@@ -53,6 +53,10 @@
 #  include <arch/rv32im/irq.h>
 #endif
 
+#if defined(CONFIG_ARCH_RV64GC)
+#  include <arch/rv64gc/irq.h>
+#endif
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/include/k210/chip.h
similarity index 51%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to arch/risc-v/include/k210/chip.h
index 6746e43..069a4c9 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/include/k210/chip.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * arch/risc-v/include/k210/chip.h
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -14,9 +14,6 @@
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -33,41 +30,7 @@
  *
  ****************************************************************************/
 
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdint.h>
-#include <debug.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include "up_arch.h"
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: modifyreg32
- *
- * Description:
- *   Atomically modify the specified bits in a memory mapped register
- *
- ****************************************************************************/
-
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
-{
-  irqstate_t flags;
-  uint32_t   regval;
+#ifndef __ARCH_RISCV_INCLUDE_K210_CHIP_H
+#define __ARCH_RISCV_INCLUDE_K210_CHIP_H
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
-}
+#endif /* __ARCH_RISCV_INCLUDE_K210_CHIP_H */
diff --git a/arch/risc-v/include/syscall.h b/arch/risc-v/include/k210/irq.h
similarity index 54%
copy from arch/risc-v/include/syscall.h
copy to arch/risc-v/include/k210/irq.h
index 1616cb4..3e32985 100644
--- a/arch/risc-v/include/syscall.h
+++ b/arch/risc-v/include/k210/irq.h
@@ -1,10 +1,8 @@
 /****************************************************************************
- * arch/risc-v/include/syscall.h
+ * arch/risc-v/include/k210/irq.h
  *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- *   Modified 2016 by Ken Pettit for RISC-V architecture.
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -16,9 +14,6 @@
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -35,45 +30,73 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through include/syscall.h or include/sys/sycall.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_SYSCALL_H
-#define __ARCH_RISCV_INCLUDE_SYSCALL_H
+#ifndef __ARCH_RISCV_INCLUDE_K210_IRQ_H
+#define __ARCH_RISCV_INCLUDE_K210_IRQ_H
 
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
-/* Include RISC-V architecture-specific syscall macros */
-
-#ifdef CONFIG_ARCH_RV32IM
-# include <arch/rv32im/syscall.h>
-#endif
+#include <arch/irq.h>
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
+/* Machine Interrupt Enable bit in mstatus register */
+
+#define MSTATUS_MIE  (0x1 << 3)
+
+/* In mie (machine interrupt enable) register */
+
+#define MIE_MTIE      (0x1 << 7)  /* Machine Timer Interrupt Enable */
+#define MIE_MEIE      (0x1 << 11) /* Machine External Interrupt Enable */
+
+/* Map RISC-V exception code to NuttX IRQ */
+
+/* IRQ 0-15 : (exception:interrupt=0) */
+
+#define K210_IRQ_IAMISALIGNED  (0) /* Instruction Address Misaligned */
+#define K210_IRQ_IAFAULT       (1) /* Instruction Address Fault */
+#define K210_IRQ_IINSTRUCTION  (2) /* Illegal Instruction */
+#define K210_IRQ_BPOINT        (3) /* Break Point */
+#define K210_IRQ_LAMISALIGNED  (4) /* Load Address Misaligned */
+#define K210_IRQ_LAFAULT       (5) /* Load Access Fault */
+#define K210_IRQ_SAMISALIGNED  (6) /* Store/AMO Address Misaligned */
+#define K210_IRQ_SAFAULT       (7) /* Store/AMO Access Fault */
+#define K210_IRQ_ECALLU        (8) /* Environment Call from U-mode */
+                                    /* 9-10: Reserved */
+
+#define K210_IRQ_ECALLM       (11) /* Environment Call from M-mode */
+                                    /* 12-15: Reserved */
+
+/* IRQ 16- : (async event:interrupt=1) */
+
+#define K210_IRQ_ASYNC        (16)
+#define K210_IRQ_MSOFT    (K210_IRQ_ASYNC + 3)  /* Machine Software Int */
+#define K210_IRQ_MTIMER   (K210_IRQ_ASYNC + 7)  /* Machine Timer Int */
+#define K210_IRQ_MEXT     (K210_IRQ_ASYNC + 11) /* Machine External Int */
+
+/* Machine Grobal External Interrupt */
+
+#define K210_IRQ_UART0    (K210_IRQ_MEXT + 33)
+
+/* Total number of IRQs */
+
+#define NR_IRQS            (K210_IRQ_UART0 + 1)
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
 
-/****************************************************************************
- * Inline functions
- ****************************************************************************/
+#ifndef __ASSEMBLY__
 
 /****************************************************************************
  * Public Data
  ****************************************************************************/
 
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#ifndef __ASSEMBLY__
-#ifdef __cplusplus
+#undef EXTERN
+#if defined(__cplusplus)
 #define EXTERN extern "C"
 extern "C"
 {
@@ -81,11 +104,18 @@ extern "C"
 #define EXTERN extern
 #endif
 
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+EXTERN irqstate_t  up_irq_save(void);
+EXTERN void up_irq_restore(irqstate_t);
+EXTERN irqstate_t up_irq_enable(void);
+
 #undef EXTERN
-#ifdef __cplusplus
+#if defined(__cplusplus)
 }
 #endif
-#endif
-
-#endif /* __ARCH_RISCV_INCLUDE_SYSCALL_H */
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_INCLUDE_K210_IRQ_H */
 
diff --git a/arch/risc-v/include/limits.h b/arch/risc-v/include/limits.h
index c3b810e..e6bae9d 100644
--- a/arch/risc-v/include/limits.h
+++ b/arch/risc-v/include/limits.h
@@ -87,4 +87,20 @@
 
 #endif /* defined(CONFIG_ARCH_32IM) || defined(CONFIG_ARCH_32I) */
 
+#if defined(CONFIG_ARCH_RV64GC)
+
+#define LONG_MIN    (-LONG_MAX - 1)
+#define LONG_MAX    9223372036854775807L
+#define ULONG_MAX   18446744073709551615UL
+
+#define LLONG_MIN   (-LLONG_MAX - 1)
+#define LLONG_MAX   9223372036854775807LL
+#define ULLONG_MAX  18446744073709551615ULL
+
+#define PTR_MIN     (-PTR_MAX - 1)
+#define PTR_MAX     9223372036854775807
+#define UPTR_MAX    18446744073709551615U
+
+#endif
+
 #endif /* __ARCH_RISCV_INCLUDE_LIMITS_H */
diff --git a/arch/risc-v/include/rv64gc/irq.h b/arch/risc-v/include/rv64gc/irq.h
new file mode 100644
index 0000000..a39a0ac
--- /dev/null
+++ b/arch/risc-v/include/rv64gc/irq.h
@@ -0,0 +1,352 @@
+/****************************************************************************
+ * arch/risc-v/include/rv64gc/irq.h
+ *
+ *   Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ *   Modified for RISC-V:
+ *
+ *   Copyright (C) 2016 Ken Pettit. All rights reserved.
+ *   Author: Ken Pettit <pe...@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/* This file should never be included directed but, rather, only indirectly
+ * through nuttx/irq.h
+ */
+
+#ifndef __ARCH_RISCV_INCLUDE_RV64GC_IRQ_H
+#define __ARCH_RISCV_INCLUDE_RV64GC_IRQ_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <arch/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/* If this is a kernel build, how many nested system calls should we support? */
+
+#ifndef CONFIG_SYS_NNEST
+#  define CONFIG_SYS_NNEST 2
+#endif
+
+/* Processor PC */
+
+#define REG_EPC_NDX         0
+
+/* General pupose registers
+ * $0: Zero register does not need to be saved
+ * $1: ra (return address)
+ */
+
+#define REG_X1_NDX          1
+
+/* $2: Stack POinter
+ * $3: Global Pointer
+ * $4: Thread Pointer
+ */
+
+#define REG_X2_NDX          2
+#define REG_X3_NDX          3
+#define REG_X4_NDX          4
+
+/* $5-$7 = t0-t3: Temporary registers */
+
+#define REG_X5_NDX          5
+#define REG_X6_NDX          6
+#define REG_X7_NDX          7
+
+/* $8: s0 / fp Frame pointer */
+
+#define REG_X8_NDX          8
+
+/* $89 s1 Saved register */
+
+#define REG_X9_NDX          9
+
+/* $10-$17 = a0-a7: Argument registers */
+
+#define REG_X10_NDX         10
+#define REG_X11_NDX         11
+#define REG_X12_NDX         12
+#define REG_X13_NDX         13
+#define REG_X14_NDX         14
+#define REG_X15_NDX         15
+#define REG_X16_NDX         16
+#define REG_X17_NDX         17
+
+/* $18-$27 = s2-s11: Saved registers */
+
+#define REG_X18_NDX         18
+#define REG_X19_NDX         19
+#define REG_X20_NDX         20
+#define REG_X21_NDX         21
+#define REG_X22_NDX         22
+#define REG_X23_NDX         23
+#define REG_X24_NDX         24
+#define REG_X25_NDX         25
+#define REG_X26_NDX         26
+#define REG_X27_NDX         27
+
+/* $28-31 = t3-t6: Temporary (Volatile) registers */
+
+#define REG_X28_NDX         28
+#define REG_X29_NDX         29
+#define REG_X30_NDX         30
+#define REG_X31_NDX         31
+
+/* Interrupt Context register */
+
+#define REG_INT_CTX_NDX     32
+
+#define XCPTCONTEXT_REGS    33
+
+#define XCPTCONTEXT_SIZE    (8*XCPTCONTEXT_REGS)
+
+/* In assembly language, values have to be referenced as byte address
+ * offsets.  But in C, it is more convenient to reference registers as
+ * register save table offsets.
+ */
+
+#ifdef __ASSEMBLY__
+#  define REG_EPC           (8*REG_EPC_NDX)
+#  define REG_X1            (8*REG_X1_NDX)
+#  define REG_X2            (8*REG_X2_NDX)
+#  define REG_X3            (8*REG_X3_NDX)
+#  define REG_X4            (8*REG_X4_NDX)
+#  define REG_X5            (8*REG_X5_NDX)
+#  define REG_X6            (8*REG_X6_NDX)
+#  define REG_X7            (8*REG_X7_NDX)
+#  define REG_X8            (8*REG_X8_NDX)
+#  define REG_X9            (8*REG_X9_NDX)
+#  define REG_X10           (8*REG_X10_NDX)
+#  define REG_X11           (8*REG_X11_NDX)
+#  define REG_X12           (8*REG_X12_NDX)
+#  define REG_X13           (8*REG_X13_NDX)
+#  define REG_X14           (8*REG_X14_NDX)
+#  define REG_X15           (8*REG_X15_NDX)
+#  define REG_X16           (8*REG_X16_NDX)
+#  define REG_X17           (8*REG_X17_NDX)
+#  define REG_X18           (8*REG_X18_NDX)
+#  define REG_X19           (8*REG_X19_NDX)
+#  define REG_X20           (8*REG_X20_NDX)
+#  define REG_X21           (8*REG_X21_NDX)
+#  define REG_X22           (8*REG_X22_NDX)
+#  define REG_X23           (8*REG_X23_NDX)
+#  define REG_X24           (8*REG_X24_NDX)
+#  define REG_X25           (8*REG_X25_NDX)
+#  define REG_X26           (8*REG_X26_NDX)
+#  define REG_X27           (8*REG_X27_NDX)
+#  define REG_X28           (8*REG_X28_NDX)
+#  define REG_X29           (8*REG_X29_NDX)
+#  define REG_X30           (8*REG_X30_NDX)
+#  define REG_X31           (8*REG_X31_NDX)
+#  define REG_INT_CTX       (8*REG_INT_CTX_NDX)
+#else
+#  define REG_EPC           REG_EPC_NDX
+#  define REG_X1            REG_X1_NDX
+#  define REG_X2            REG_X2_NDX
+#  define REG_X3            REG_X3_NDX
+#  define REG_X4            REG_X4_NDX
+#  define REG_X5            REG_X5_NDX
+#  define REG_X6            REG_X6_NDX
+#  define REG_X7            REG_X7_NDX
+#  define REG_X8            REG_X8_NDX
+#  define REG_X9            REG_X9_NDX
+#  define REG_X10           REG_X10_NDX
+#  define REG_X11           REG_X11_NDX
+#  define REG_X12           REG_X12_NDX
+#  define REG_X13           REG_X13_NDX
+#  define REG_X14           REG_X14_NDX
+#  define REG_X15           REG_X15_NDX
+#  define REG_X16           REG_X16_NDX
+#  define REG_X17           REG_X17_NDX
+#  define REG_X18           REG_X18_NDX
+#  define REG_X19           REG_X19_NDX
+#  define REG_X20           REG_X20_NDX
+#  define REG_X21           REG_X21_NDX
+#  define REG_X22           REG_X22_NDX
+#  define REG_X23           REG_X23_NDX
+#  define REG_X24           REG_X24_NDX
+#  define REG_X25           REG_X25_NDX
+#  define REG_X26           REG_X26_NDX
+#  define REG_X27           REG_X27_NDX
+#  define REG_X28           REG_X28_NDX
+#  define REG_X29           REG_X29_NDX
+#  define REG_X30           REG_X30_NDX
+#  define REG_X31           REG_X31_NDX
+#  define REG_INT_CTX       REG_INT_CTX_NDX
+#endif
+
+/* Now define more user friendly alternative name that can be used either
+ * in assembly or C contexts.
+ */
+
+/* $1 = ra: Return address */
+
+#define REG_RA              REG_X1
+
+/* $2 = sp:  The value of the stack pointer on return from the exception */
+
+#define REG_SP              REG_X2
+
+/* $3 = gp: Only needs to be saved under conditions where there are
+ * multiple, per-thread values for the GP.
+ */
+
+#define REG_GP              REG_X3
+
+/* $4 = tp:  Thread Pointer */
+
+#define REG_TP              REG_X4
+
+/* $5-$7 = t0-t2: Caller saved temporary registers */
+
+#define REG_T0              REG_X5
+#define REG_T1              REG_X6
+#define REG_T2              REG_X7
+
+/* $8 = either s0 or fp:  Depends if a frame pointer is used or not */
+
+#define REG_S0              REG_X8
+#define REG_FP              REG_X8
+
+/* $9 = s1: Caller saved register */
+
+#define REG_S1              REG_X9
+
+/* $10-$17 = a0-a7: Argument registers */
+
+#define REG_A0              REG_X10
+#define REG_A1              REG_X11
+#define REG_A2              REG_X12
+#define REG_A3              REG_X13
+#define REG_A4              REG_X14
+#define REG_A5              REG_X15
+#define REG_A6              REG_X16
+#define REG_A7              REG_X17
+
+/* $18-$27 = s2-s11: Callee saved registers */
+
+#define REG_S2              REG_X18
+#define REG_S3              REG_X19
+#define REG_S4              REG_X20
+#define REG_S5              REG_X21
+#define REG_S6              REG_X22
+#define REG_S7              REG_X23
+#define REG_S8              REG_X24
+#define REG_S9              REG_X25
+#define REG_S10             REG_X26
+#define REG_S11             REG_X27
+
+/* $28-$31 = t3-t6: Caller saved temporary registers */
+
+#define REG_T3              REG_X28
+#define REG_T4              REG_X29
+#define REG_T5              REG_X30
+#define REG_T6              REG_X31
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/* This structure represents the return state from a system call */
+
+#ifdef CONFIG_BUILD_KERNEL
+struct xcpt_syscall_s
+{
+  uint64_t sysreturn;   /* The return PC */
+};
+#endif
+
+/* The following structure is included in the TCB and defines the complete
+ * state of the thread.
+ */
+
+struct xcptcontext
+{
+  /* The following function pointer is non-NULL if there are pending signals
+   * to be processed.
+   */
+
+  void *sigdeliver; /* Actual type is sig_deliver_t */
+
+  /* These additional register save locations are used to implement the
+   * signal delivery trampoline.
+   *
+   * REVISIT:  Because there is only one copy of these save areas,
+   * only a single signal handler can be active.  This precludes
+   * queuing of signal actions.  As a result, signals received while
+   * another signal handler is executing will be ignored!
+   */
+
+  uint64_t saved_epc;     /* Trampoline PC */
+  uint64_t saved_int_ctx; /* Interrupt context with interrupts disabled. */
+
+#ifdef CONFIG_BUILD_KERNEL
+  /* This is the saved address to use when returning from a user-space
+   * signal handler.
+   */
+
+  uint32_t sigreturn;
+#endif
+
+#ifdef CONFIG_BUILD_KERNEL
+  /* The following array holds information needed to return from each nested
+   * system call.
+   */
+
+  uint8_t nsyscalls;
+  struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST];
+
+#endif
+
+  /* Register save area */
+
+  uint64_t regs[XCPTCONTEXT_REGS];
+};
+
+#endif  /* __ASSEMBLY__ */
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#endif /* __ARCH_RISCV_INCLUDE_RV64GC_IRQ_H */
diff --git a/arch/risc-v/include/rv64gc/syscall.h b/arch/risc-v/include/rv64gc/syscall.h
new file mode 100644
index 0000000..009b361
--- /dev/null
+++ b/arch/risc-v/include/rv64gc/syscall.h
@@ -0,0 +1,209 @@
+/****************************************************************************
+ * arch/risc-v/include/rv64gc/syscall.h
+ *
+ *   Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/* This file should never be included directed but, rather, only indirectly
+ * through include/syscall.h or include/sys/sycall.h
+ */
+
+#ifndef __ARCH_RISCV_INCLUDE_RV64GC_SYSCALL_H
+#define __ARCH_RISCV_INCLUDE_RV64GC_SYSCALL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifndef __ASSEMBLY__
+#  include <stdint.h>
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SYS_syscall 0x00
+
+/* Configuration ************************************************************/
+
+/* SYS call 1 and 2 are defined for internal use by the RISC-V port (see
+ * arch/risc-v/include/rv64gc/syscall.h).  In addition, SYS call 3 is the
+ * return from a SYS call in kernel mode.  The first four syscall values must,
+ * therefore, be reserved (0 is not used).
+ */
+
+#ifdef CONFIG_BUILD_KERNEL
+#  ifndef CONFIG_SYS_RESERVED
+#    error "CONFIG_SYS_RESERVED must be defined to the value 4"
+#  elif CONFIG_SYS_RESERVED != 4
+#    error "CONFIG_SYS_RESERVED must have the value 4"
+#  endif
+#endif
+
+/* sys_call macros **********************************************************/
+
+#ifndef __ASSEMBLY__
+
+/* Context switching system calls *******************************************/
+
+/* SYS call 0: (not used) */
+
+/* SYS call 1:
+ *
+ * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
+ */
+
+#define SYS_restore_context (1)
+#define up_fullcontextrestore(restoreregs) \
+  (void)sys_call1(SYS_restore_context, (uintptr_t)restoreregs)
+
+/* SYS call 2:
+ *
+ * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs);
+ */
+
+#define SYS_switch_context (2)
+#define up_switchcontext(saveregs, restoreregs) \
+  (void)sys_call2(SYS_switch_context, (uintptr_t)saveregs, (uintptr_t)restoreregs)
+
+#ifdef CONFIG_BUILD_KERNEL
+/* SYS call 3:
+ *
+ * void up_syscall_return(void);
+ */
+
+#define SYS_syscall_return (3)
+#define up_syscall_return() (void)sys_call0(SYS_syscall_return)
+
+#endif
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: up_syscall0
+ *
+ * Description:
+ *   System call SYS_ argument and no additional parameters.
+ *
+ ****************************************************************************/
+
+uintptr_t sys_call0(unsigned int nbr);
+
+/****************************************************************************
+ * Name: up_syscall1
+ *
+ * Description:
+ *   System call SYS_ argument and one additional parameter.
+ *
+ ****************************************************************************/
+
+uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1);
+
+/****************************************************************************
+ * Name: up_syscall2
+ *
+ * Description:
+ *   System call SYS_ argument and two additional parameters.
+ *
+ ****************************************************************************/
+
+uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, uintptr_t parm2);
+
+/****************************************************************************
+ * Name: up_syscall3
+ *
+ * Description:
+ *   System call SYS_ argument and three additional parameters.
+ *
+ ****************************************************************************/
+
+uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
+                    uintptr_t parm3);
+
+/****************************************************************************
+ * Name: up_syscall4
+ *
+ * Description:
+ *   System call SYS_ argument and four additional parameters.
+ *
+ ****************************************************************************/
+
+uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
+                    uintptr_t parm3, uintptr_t parm4);
+
+/****************************************************************************
+ * Name: up_syscall5
+ *
+ * Description:
+ *   System call SYS_ argument and five additional parameters.
+ *
+ ****************************************************************************/
+
+uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
+                    uintptr_t parm3, uintptr_t parm4, uintptr_t parm5);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_INCLUDE_RV64GC_SYSCALL_H */
+
diff --git a/arch/risc-v/include/syscall.h b/arch/risc-v/include/syscall.h
index 1616cb4..37a705a 100644
--- a/arch/risc-v/include/syscall.h
+++ b/arch/risc-v/include/syscall.h
@@ -52,6 +52,10 @@
 # include <arch/rv32im/syscall.h>
 #endif
 
+#ifdef CONFIG_ARCH_RV64GC
+# include <arch/rv64gc/syscall.h>
+#endif
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
diff --git a/arch/risc-v/include/types.h b/arch/risc-v/include/types.h
index 8b7b094..08344fc 100644
--- a/arch/risc-v/include/types.h
+++ b/arch/risc-v/include/types.h
@@ -78,10 +78,17 @@ typedef signed long long   _int64_t;
 typedef unsigned long long _uint64_t;
 #define __INT64_DEFINED
 
+#ifdef __LP64__
+/* A pointer is 8 bytes */
+
+typedef signed long         _intptr_t;
+typedef unsigned long       _uintptr_t;
+#else
 /* A pointer is 4 bytes */
 
 typedef signed int         _intptr_t;
 typedef unsigned int       _uintptr_t;
+#endif
 
 /* This is the size of the interrupt state save returned by irqsave().  */
 
diff --git a/arch/risc-v/src/Makefile b/arch/risc-v/src/Makefile
index e69ec45..d4057f1 100644
--- a/arch/risc-v/src/Makefile
+++ b/arch/risc-v/src/Makefile
@@ -42,6 +42,8 @@ ifeq ($(CONFIG_ARCH_RV32I),y)           # Base Integer support
 ARCH_SUBDIR = rv32i
 else ifeq ($(CONFIG_ARCH_RV32IM),y)     # Integer + math support
 ARCH_SUBDIR = rv32im
+else ifeq ($(CONFIG_ARCH_RV64GC),y)     # GC=IMAFDC
+ARCH_SUBDIR = rv64gc
 else
 ARCH_SUBDIR = rv32i                     # Default to base RV32I core
 endif
diff --git a/arch/risc-v/src/common/up_arch.h b/arch/risc-v/src/common/up_arch.h
index ee7ed9c..9184acc 100644
--- a/arch/risc-v/src/common/up_arch.h
+++ b/arch/risc-v/src/common/up_arch.h
@@ -77,7 +77,7 @@ extern "C"
 
 /* Atomic modification of registers */
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits);
+void modifyreg32(uintptr_t addr, uint32_t clearbits, uint32_t setbits);
 
 #undef EXTERN
 #if defined(__cplusplus)
diff --git a/arch/risc-v/src/common/up_createstack.c b/arch/risc-v/src/common/up_createstack.c
index 971a69f..499f8bb 100644
--- a/arch/risc-v/src/common/up_createstack.c
+++ b/arch/risc-v/src/common/up_createstack.c
@@ -60,7 +60,7 @@
  * however, the stack must be aligned to 8-byte addresses.
  */
 
-#ifdef CONFIG_LIBC_FLOATINGPOINT
+#if defined(CONFIG_LIBC_FLOATINGPOINT) || defined (CONFIG_ARCH_RV64GC)
 #  define STACK_ALIGNMENT   8
 #else
 #  define STACK_ALIGNMENT   4
@@ -181,7 +181,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * the stack are referenced as positive word offsets from sp.
        */
 
-      top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size - 4;
 
       /* The MIPS stack must be aligned at word (4 byte) boundaries; for
        * floating point use, the stack must be aligned to 8-byte addresses.
@@ -190,7 +190,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
-      size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr + 4;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
diff --git a/arch/risc-v/src/common/up_internal.h b/arch/risc-v/src/common/up_internal.h
index 703a1e8..3e84353 100644
--- a/arch/risc-v/src/common/up_internal.h
+++ b/arch/risc-v/src/common/up_internal.h
@@ -69,7 +69,11 @@
  * only a referenced is passed to get the state from the TCB.
  */
 
+#ifdef CONFIG_ARCH_RV64GC
+#define up_savestate(regs)    up_copystate(regs, (uint64_t*)g_current_regs)
+#else
 #define up_savestate(regs)    up_copystate(regs, (uint32_t*)g_current_regs)
+#endif
 #define up_restorestate(regs) (g_current_regs = regs)
 
 /* Determine which (if any) console driver to use.  If a console is enabled
@@ -113,8 +117,13 @@ extern "C"
 #define EXTERN extern
 #endif
 
+#ifdef CONFIG_ARCH_RV64GC
+EXTERN volatile uint64_t *g_current_regs;
+EXTERN uintptr_t g_idle_topstack;
+#else
 EXTERN volatile uint32_t *g_current_regs;
 EXTERN uint32_t g_idle_topstack;
+#endif
 
 /* Address of the saved user stack pointer */
 
@@ -163,7 +172,12 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size);
 void up_irqinitialize(void);
 void up_ack_irq(int irq);
 
+#ifdef CONFIG_ARCH_RV64GC
+void up_copystate(uint64_t *dest, uint64_t *src);
+#else
 void up_copystate(uint32_t *dest, uint32_t *src);
+#endif
+
 void up_sigdeliver(void);
 int up_swint(int irq, FAR void *context, FAR void *arg);
 uint32_t up_get_newintctx(void);
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/src/common/up_modifyreg32.c
index 6746e43..96f9fca 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/src/common/up_modifyreg32.c
@@ -59,7 +59,7 @@
  *
  ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
+void modifyreg32(uintptr_t addr, uint32_t clearbits, uint32_t setbits)
 {
   irqstate_t flags;
   uint32_t   regval;
diff --git a/arch/risc-v/src/common/up_stackframe.c b/arch/risc-v/src/common/up_stackframe.c
index be7b797..1fe4943 100644
--- a/arch/risc-v/src/common/up_stackframe.c
+++ b/arch/risc-v/src/common/up_stackframe.c
@@ -55,7 +55,7 @@
  * however, the stack must be aligned to 8-byte addresses.
  */
 
-#ifdef CONFIG_LIBC_FLOATINGPOINT
+#if defined(CONFIG_LIBC_FLOATINGPOINT) || defined (CONFIG_ARCH_RV64GC)
 #  define STACK_ALIGNMENT   8
 #else
 #  define STACK_ALIGNMENT   4
@@ -134,10 +134,10 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 
   /* Reset the initial stack pointer */
 
-  tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+  tcb->xcp.regs[REG_SP] = (uintptr_t)tcb->adj_stack_ptr;
 
   /* And return the pointer to the allocated region */
 
-  return (FAR void *)(topaddr + sizeof(uint32_t));
+  return (FAR void *)(topaddr);
 }
 
diff --git a/arch/risc-v/src/common/up_usestack.c b/arch/risc-v/src/common/up_usestack.c
index 49333a5..353fd38 100644
--- a/arch/risc-v/src/common/up_usestack.c
+++ b/arch/risc-v/src/common/up_usestack.c
@@ -57,7 +57,7 @@
  * however, the stack must be aligned to 8-byte addresses.
  */
 
-#ifdef CONFIG_LIBC_FLOATINGPOINT
+#if defined(CONFIG_LIBC_FLOATINGPOINT) || defined (CONFIG_ARCH_RV64GC)
 #  define STACK_ALIGNMENT   8
 #else
 #  define STACK_ALIGNMENT   4
@@ -133,7 +133,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * as positive word offsets from sp.
    */
 
-  top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size - 4;
 
   /* The MIPS stack must be aligned at word (4 byte) or double word (8 byte)
    * boundaries. If necessary top_of_stack must be rounded down to the
@@ -141,11 +141,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    */
 
   top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
-  size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr + 4;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+  tcb->adj_stack_ptr  = (uintptr_t *)top_of_stack;
   tcb->adj_stack_size = size_of_stack;
 
   return OK;
diff --git a/arch/risc-v/src/k210/Kconfig b/arch/risc-v/src/k210/Kconfig
new file mode 100644
index 0000000..ed34b92
--- /dev/null
+++ b/arch/risc-v/src/k210/Kconfig
@@ -0,0 +1,28 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+comment "K210 Configuration Options"
+
+menu "K210 Peripheral Support"
+
+# These "hidden" settings determine is a peripheral option is available for the
+# selection MCU
+
+config K210_HAVE_UART0
+	bool
+	default y
+	select UART0_SERIALDRIVER
+	select ARCH_HAVE_SERIAL_TERMIOS
+
+# These are the peripheral selections proper
+
+config K210_UART0
+	bool "UART0"
+	default y
+	select ARCH_HAVE_UART0
+	select ARCH_HAVE_SERIAL_TERMIOS
+	select K210_UART
+
+endmenu
diff --git a/arch/risc-v/src/k210/Make.defs b/arch/risc-v/src/k210/Make.defs
new file mode 100644
index 0000000..08a269f
--- /dev/null
+++ b/arch/risc-v/src/k210/Make.defs
@@ -0,0 +1,62 @@
+############################################################################
+# arch/risc-v/src/k210/Make.defs
+#
+#   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+#   Author: Masayuki Ishikawa <ma...@gmail.com>
+#
+# # Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+# Specify our HEAD assembly file.  This will be linked as
+# the first object file, so it will appear at address 0
+HEAD_ASRC = k210_vectors.S
+
+# Specify our general Assembly files
+CHIP_ASRCS = k210_head.S up_syscall.S
+
+# Specify C code within the common directory to be included
+CMN_CSRCS  += up_initialize.c up_swint.c
+CMN_CSRCS  += up_allocateheap.c up_createstack.c up_exit.c
+CMN_CSRCS  += up_assert.c up_blocktask.c up_copystate.c up_initialstate.c
+CMN_CSRCS  += up_interruptcontext.c up_modifyreg32.c up_puts.c
+CMN_CSRCS  += up_releasepending.c up_reprioritizertr.c
+CMN_CSRCS  += up_releasestack.c up_stackframe.c up_schedulesigaction.c
+CMN_CSRCS  += up_sigdeliver.c up_unblocktask.c up_usestack.c
+
+ifeq ($(CONFIG_STACK_COLORATION),y)
+CMN_CSRCS += up_checkstack.c
+endif
+
+ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
+CMN_CSRCS  += up_vfork.c
+endif
+
+# Specify our C code within this directory to be included
+CHIP_CSRCS  = k210_allocateheap.c k210_clockconfig.c
+CHIP_CSRCS += k210_idle.c k210_irq.c k210_irq_dispatch.c
+CHIP_CSRCS += k210_lowputc.c k210_serial.c
+CHIP_CSRCS += k210_start.c k210_timerisr.c
+
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/src/k210/chip.h
similarity index 58%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to arch/risc-v/src/k210/chip.h
index 6746e43..6f0d7aa 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/src/k210/chip.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * arch/risc-v/src/k210/chip.h
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -14,9 +14,6 @@
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -33,41 +30,16 @@
  *
  ****************************************************************************/
 
+#ifndef __ARCH_RISCV_SRC_K210_CHIP_H
+#define __ARCH_RISCV_SRC_K210_CHIP_H
+
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
 #include <nuttx/config.h>
 
-#include <stdint.h>
-#include <debug.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include "up_arch.h"
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: modifyreg32
- *
- * Description:
- *   Atomically modify the specified bits in a memory mapped register
- *
- ****************************************************************************/
+#include "k210_memorymap.h"
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
-{
-  irqstate_t flags;
-  uint32_t   regval;
+#endif /* __ARCH_RISCV_SRC_K210_CHIP_H */
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
-}
diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/src/k210/hardware/k210_clint.h
similarity index 58%
copy from arch/risc-v/include/irq.h
copy to arch/risc-v/src/k210/hardware/k210_clint.h
index 338b9a1..9968c4f 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/src/k210/hardware/k210_clint.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/include/irq.h
+ * arch/risc-v/src/k210/hardware/k210_clint.h
  *
- *   Copyright (C) 2016 Ken Pettit. All rights reserved.
- *   Author: Ken Pettit <pe...@gmail.com>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,41 +30,14 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through nuttx/irq.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_IRQ_H
-#define __ARCH_RISCV_INCLUDE_IRQ_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-/* Include chip-specific IRQ definitions (including IRQ numbers) */
-
-#include <stdint.h>
-#include <nuttx/irq.h>
-#include <arch/chip/irq.h>
-
-/* Include RISC-V architecture-specific IRQ definitions */
-
-#if defined(CONFIG_ARCH_RV32IM) || defined(CONFIG_ARCH_RV32I)
-#  include <arch/rv32im/irq.h>
-#endif
+#ifndef __ARCH_RISCV_SRC_K210_HARDWARE_K210_CLINT_H
+#define __ARCH_RISCV_SRC_K210_HARDWARE_K210_CLINT_H
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-typedef uint32_t  irqstate_t;
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Variables
- ****************************************************************************/
+#define K210_CLINT_MTIMECMP  (K210_CLINT_BASE + 0x4000)
+#define K210_CLINT_MTIME     (K210_CLINT_BASE + 0xbff8)
 
-#endif /* __ARCH_RISCV_INCLUDE_IRQ_H */
+#endif /* __ARCH_RISCV_SRC_K210_HARDWARE_K210_CLINT_H */
diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/src/k210/hardware/k210_memorymap.h
similarity index 58%
copy from arch/risc-v/include/irq.h
copy to arch/risc-v/src/k210/hardware/k210_memorymap.h
index 338b9a1..16a6ec0 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/src/k210/hardware/k210_memorymap.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/include/irq.h
+ * arch/risc-v/src/k210/hardware/k210_memorymap.h
  *
- *   Copyright (C) 2016 Ken Pettit. All rights reserved.
- *   Author: Ken Pettit <pe...@gmail.com>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,41 +30,20 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through nuttx/irq.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_IRQ_H
-#define __ARCH_RISCV_INCLUDE_IRQ_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-/* Include chip-specific IRQ definitions (including IRQ numbers) */
-
-#include <stdint.h>
-#include <nuttx/irq.h>
-#include <arch/chip/irq.h>
-
-/* Include RISC-V architecture-specific IRQ definitions */
-
-#if defined(CONFIG_ARCH_RV32IM) || defined(CONFIG_ARCH_RV32I)
-#  include <arch/rv32im/irq.h>
-#endif
+#ifndef __ARCH_RISCV_SRC_K210_HARDWARE_K210_MEMORYMAP_H
+#define __ARCH_RISCV_SRC_K210_HARDWARE_K210_MEMORYMAP_H
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-typedef uint32_t  irqstate_t;
+/* Register Base Address ****************************************************/
 
-/****************************************************************************
- * Public Types
- ****************************************************************************/
+#define K210_CLINT_BASE   0x02000000
+#define K210_PLIC_BASE    0x0c000000
 
-/****************************************************************************
- * Public Variables
- ****************************************************************************/
+#define K210_UART0_BASE   0x38000000
+#define K210_GPIO_BASE    0x38001000
+
+#endif /* __ARCH_RISCV_SRC_K210_HARDWARE_K210_MEMORYMAP_H */
 
-#endif /* __ARCH_RISCV_INCLUDE_IRQ_H */
diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/src/k210/hardware/k210_plic.h
similarity index 58%
copy from arch/risc-v/include/irq.h
copy to arch/risc-v/src/k210/hardware/k210_plic.h
index 338b9a1..98b773b 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/src/k210/hardware/k210_plic.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/include/irq.h
+ * arch/risc-v/src/k210/hardware/k210_plic.h
  *
- *   Copyright (C) 2016 Ken Pettit. All rights reserved.
- *   Author: Ken Pettit <pe...@gmail.com>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,41 +30,18 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through nuttx/irq.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_IRQ_H
-#define __ARCH_RISCV_INCLUDE_IRQ_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-/* Include chip-specific IRQ definitions (including IRQ numbers) */
-
-#include <stdint.h>
-#include <nuttx/irq.h>
-#include <arch/chip/irq.h>
-
-/* Include RISC-V architecture-specific IRQ definitions */
-
-#if defined(CONFIG_ARCH_RV32IM) || defined(CONFIG_ARCH_RV32I)
-#  include <arch/rv32im/irq.h>
-#endif
+#ifndef __ARCH_RISCV_SRC_K210_HARDWARE_K210_PLIC_H
+#define __ARCH_RISCV_SRC_K210_HARDWARE_K210_PLIC_H
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-typedef uint32_t  irqstate_t;
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Variables
- ****************************************************************************/
+#define K210_PLIC_PRIORITY    (K210_PLIC_BASE + 0x000000)
+#define K210_PLIC_PENDING1    (K210_PLIC_BASE + 0x001000)
+#define K210_PLIC_ENABLE1     (K210_PLIC_BASE + 0x002000)
+#define K210_PLIC_ENABLE2     (K210_PLIC_BASE + 0x002004)
+#define K210_PLIC_THRESHOLD   (K210_PLIC_BASE + 0x200000)
+#define K210_PLIC_CLAIM       (K210_PLIC_BASE + 0x200004)
 
-#endif /* __ARCH_RISCV_INCLUDE_IRQ_H */
+#endif /* __ARCH_RISCV_SRC_K210_HARDWARE_K210_PLIC_H */
diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/src/k210/hardware/k210_uart.h
similarity index 50%
copy from arch/risc-v/include/irq.h
copy to arch/risc-v/src/k210/hardware/k210_uart.h
index 338b9a1..cbd694a 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/src/k210/hardware/k210_uart.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/include/irq.h
+ * arch/risc-v/src/k210/hardware/k210_uart.h
  *
- *   Copyright (C) 2016 Ken Pettit. All rights reserved.
- *   Author: Ken Pettit <pe...@gmail.com>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,41 +30,43 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through nuttx/irq.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_IRQ_H
-#define __ARCH_RISCV_INCLUDE_IRQ_H
+#ifndef ARCH_RISCV_SRC_K210_CHIP_K210_UART_H
+#define ARCH_RISCV_SRC_K210_CHIP_K210_UART_H
 
 /****************************************************************************
- * Included Files
+ * Pre-processor Definitions
  ****************************************************************************/
 
-/* Include chip-specific IRQ definitions (including IRQ numbers) */
-
-#include <stdint.h>
-#include <nuttx/irq.h>
-#include <arch/chip/irq.h>
+#define UART_TXDATA_OFFSET   0x00
+#define UART_RXDATA_OFFSET   0x04
+#define UART_TXCTL_OFFSET    0x08
+#define UART_RXCTL_OFFSET    0x0c
+#define UART_IE_OFFSET       0x10
+#define UART_IP_OFFSET       0x14
+#define UART_DIV_OFFSET      0x18
 
-/* Include RISC-V architecture-specific IRQ definitions */
-
-#if defined(CONFIG_ARCH_RV32IM) || defined(CONFIG_ARCH_RV32I)
-#  include <arch/rv32im/irq.h>
+#ifdef CONFIG_K210_UART0
+#  define K210_UART0_TXDATA  (K210_UART0_BASE + UART_TXDATA_OFFSET)
+#  define K210_UART0_RXDATA  (K210_UART0_BASE + UART_RXDATA_OFFSET)
+#  define K210_UART0_TXCTRL  (K210_UART0_BASE + UART_TXCTRL_OFFSET)
+#  define K210_UART0_RXCTRL  (K210_UART0_BASE + UART_RXCTRL_OFFSET)
+#  define K210_UART0_IE      (K210_UART0_BASE + UART_IE_OFFSET)
+#  define K210_UART0_IP      (K210_UART0_BASE + UART_IP_OFFSET)
+#  define K210_UART0_DIV     (K210_UART0_BASE + UART_DIV_OFFSET)
 #endif
 
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
+#define UART_TX_FULL   (1 << 31) /* TX FIFO full  (in TXDATA) */
+#define UART_RX_EMPTY  (1 << 31) /* RX FIFO empty (in RXDATA) */
 
-typedef uint32_t  irqstate_t;
+#define UART_TX_EN     (1 << 0)  /* Enable TX (in TXCTL) */
+#define UART_NSTOP     (1 << 1)  /* Number of stop bits (in TXCTL) */
 
-/****************************************************************************
- * Public Types
- ****************************************************************************/
+#define UART_RX_EN     (1 << 0)  /* Enable RX (in RXCTL) */
 
-/****************************************************************************
- * Public Variables
- ****************************************************************************/
+#define UART_IE_TXWM   (1 << 0)  /* Enable TX wartermark int (in IE) */
+#define UART_IE_RXWM   (1 << 1)  /* Enable RX wartermark int (in IE) */
+
+#define UART_IP_TXWM   (1 << 0)  /* TX wartermark pending (in IP) */
+#define UART_IP_RXWM   (1 << 1)  /* RX wartermark pending (in IP) */
 
-#endif /* __ARCH_RISCV_INCLUDE_IRQ_H */
+#endif  /* _ARCH_RISCV_SRC_K210_CHIP_K210_UART_H */
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/src/k210/k210.h
similarity index 66%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to arch/risc-v/src/k210/k210.h
index 6746e43..2c16714 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/src/k210/k210.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * arch/risc-v/src/k210/k210.h
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,41 +33,22 @@
  *
  ****************************************************************************/
 
+#ifndef __ARCH_RISCV_SRC_K210_K210_H
+#define __ARCH_RISCV_SRC_K210_K210_H
+
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
 #include <nuttx/config.h>
-
+#include <sys/types.h>
 #include <stdint.h>
-#include <debug.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
+#include <stdbool.h>
 
-#include "up_arch.h"
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: modifyreg32
- *
- * Description:
- *   Atomically modify the specified bits in a memory mapped register
- *
- ****************************************************************************/
+#include <arch/irq.h>
+#include "up_internal.h"
+#include "chip.h"
+#include "k210_lowputc.h"
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
-{
-  irqstate_t flags;
-  uint32_t   regval;
+#endif /* __ARCH_RISCV_SRC_K210_K210_H */
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
-}
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/src/k210/k210_allocateheap.c
similarity index 70%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to arch/risc-v/src/k210/k210_allocateheap.c
index 6746e43..6f82aa3 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/src/k210/k210_allocateheap.c
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * arch/risc-v/src/k210/k210_allocateheap.c
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -14,9 +14,6 @@
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -39,35 +36,19 @@
 
 #include <nuttx/config.h>
 
-#include <stdint.h>
-#include <debug.h>
+#include <arch/board/board.h>
 
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include "up_arch.h"
+#include "k210.h"
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: modifyreg32
- *
- * Description:
- *   Atomically modify the specified bits in a memory mapped register
- *
+ * Name: up_addregion
  ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
+void up_addregion(void)
 {
-  irqstate_t flags;
-  uint32_t   regval;
-
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
 }
+
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/src/k210/k210_clockconfig.c
similarity index 75%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to arch/risc-v/src/k210/k210_clockconfig.c
index 6746e43..e5ace3e 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/src/k210/k210_clockconfig.c
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * arch/arm/src/k210/k210_clockconfig.c
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,34 +40,37 @@
 #include <nuttx/config.h>
 
 #include <stdint.h>
+#include <assert.h>
 #include <debug.h>
 
-#include <nuttx/irq.h>
 #include <nuttx/arch.h>
+#include <arch/board/board.h>
 
 #include "up_arch.h"
+#include "k210_clockconfig.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: modifyreg32
- *
- * Description:
- *   Atomically modify the specified bits in a memory mapped register
- *
+ * Name: k210_get_cpuclk
  ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
+uint32_t k210_get_cpuclk(void)
 {
-  irqstate_t flags;
-  uint32_t   regval;
+  return 416000000; /* TODO */
+}
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
+/****************************************************************************
+ * Name: k210_clockconfig
+ ****************************************************************************/
+
+void k210_clockconfig(void)
+{
+  /* TODO */
 }
diff --git a/arch/risc-v/include/syscall.h b/arch/risc-v/src/k210/k210_clockconfig.h
similarity index 76%
copy from arch/risc-v/include/syscall.h
copy to arch/risc-v/src/k210/k210_clockconfig.h
index 1616cb4..8a34e37 100644
--- a/arch/risc-v/include/syscall.h
+++ b/arch/risc-v/src/k210/k210_clockconfig.h
@@ -1,10 +1,8 @@
 /****************************************************************************
- * arch/risc-v/include/syscall.h
+ * arch/arm/src/k210/k210_clockconfig.h
  *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- *   Modified 2016 by Ken Pettit for RISC-V architecture.
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,22 +33,14 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through include/syscall.h or include/sys/sycall.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_SYSCALL_H
-#define __ARCH_RISCV_INCLUDE_SYSCALL_H
+#ifndef __ARCH_RISCV_SRC_K210_K210_CLOCKCONFIG_H
+#define __ARCH_RISCV_SRC_K210_K210_CLOCKCONFIG_H
 
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
-/* Include RISC-V architecture-specific syscall macros */
-
-#ifdef CONFIG_ARCH_RV32IM
-# include <arch/rv32im/syscall.h>
-#endif
+#include "k210_memorymap.h"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -60,19 +50,12 @@
  * Public Types
  ****************************************************************************/
 
-/****************************************************************************
- * Inline functions
- ****************************************************************************/
+#ifndef __ASSEMBLY__
 
 /****************************************************************************
  * Public Data
  ****************************************************************************/
 
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#ifndef __ASSEMBLY__
 #ifdef __cplusplus
 #define EXTERN extern "C"
 extern "C"
@@ -81,11 +64,17 @@ extern "C"
 #define EXTERN extern
 #endif
 
-#undef EXTERN
-#ifdef __cplusplus
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+EXTERN uint32_t k210_get_cpuclk(void);
+EXTERN void k210_clockconfig(void);
+
+#if defined(__cplusplus)
 }
 #endif
-#endif
-
-#endif /* __ARCH_RISCV_INCLUDE_SYSCALL_H */
+#undef EXTERN
 
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_SRC_K210_K210_CLOCKCONFIG_H */
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/src/k210/k210_config.h
similarity index 69%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to arch/risc-v/src/k210/k210_config.h
index 6746e43..68b45b2 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/src/k210/k210_config.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * arch/risc-v/src/k210/k210_config.h
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,41 +33,37 @@
  *
  ****************************************************************************/
 
+#ifndef __ARCH_RISCV_SRC_K210_K210_CONFIG_H
+#define __ARCH_RISCV_SRC_K210_K210_CONFIG_H
+
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
 #include <nuttx/config.h>
 
-#include <stdint.h>
-#include <debug.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include "up_arch.h"
+#include <arch/chip/chip.h>
+#include <arch/board/board.h>
 
 /****************************************************************************
- * Public Functions
+ * Pre-processor Definitions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: modifyreg32
- *
- * Description:
- *   Atomically modify the specified bits in a memory mapped register
- *
- ****************************************************************************/
+#undef HAVE_UART_DEVICE
+#if defined(CONFIG_K210_UART0) || defined(CONFIG_K210_UART1)
+#  define HAVE_UART_DEVICE 1
+#endif
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
-{
-  irqstate_t flags;
-  uint32_t   regval;
+#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_K210_UART0)
+#  undef CONFIG_UART1_SERIAL_CONSOLE
+#  define HAVE_SERIAL_CONSOLE 1
+#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_K210_UART1)
+#  undef CONFIG_UART0_SERIAL_CONSOLE
+#  define HAVE_SERIAL_CONSOLE 1
+#else
+#  undef CONFIG_UART0_SERIAL_CONSOLE
+#  undef CONFIG_UART1_SERIAL_CONSOLE
+#  undef HAVE_SERIAL_CONSOLE
+#endif
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
-}
+#endif /* __ARCH_RISCV_SRC_K210_K210_CONFIG_H */
diff --git a/arch/risc-v/src/k210/k210_head.S b/arch/risc-v/src/k210/k210_head.S
new file mode 100644
index 0000000..291d549
--- /dev/null
+++ b/arch/risc-v/src/k210/k210_head.S
@@ -0,0 +1,213 @@
+/****************************************************************************
+ * arch/risc-v/src/k210/k210_head.S
+ *
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <arch/rv64gc/irq.h>
+
+#include "chip.h"
+
+/****************************************************************************
+ * Public Symbols
+ ****************************************************************************/
+
+  .global exception_common
+
+  /* Imported symbols */
+
+  .extern __trap_vec
+
+  .section .text
+  .global __start
+
+__start:
+
+  /* Set stack pointer to the idle thread stack */
+
+  la  sp, K210_IDLESTACK_TOP
+
+  /* Disable all interrupts (i.e. timer, external) in mie */
+
+  csrw mie, zero
+
+  /* Initialize the Machine Trap Vector */
+
+  la   t0, __trap_vec
+  csrw mtvec, t0
+
+  /* Jump to __k210_start */
+
+  jal  x1, __k210_start
+
+  /* We shouldn't return from __k210_start */
+
+  .global _init
+  .global _fini
+
+_init:
+_fini:
+
+  /* These don't have to do anything since we use init_array/fini_array. */
+
+  ret
+
+/****************************************************************************
+ * Name: exception_common
+ ****************************************************************************/
+
+exception_common:
+
+  addi sp, sp, -XCPTCONTEXT_SIZE
+
+  sd   x1,  1*8(sp)   /* ra */
+  sd   x3,  3*8(sp)   /* gp */
+  sd   x4,  4*8(sp)   /* tp */
+  sd   x5,  5*8(sp)   /* t0 */
+  sd   x6,  6*8(sp)   /* t1 */
+  sd   x7,  7*8(sp)   /* t2 */
+  sd   x8,  8*8(sp)   /* s0 */
+  sd   x9,  9*8(sp)   /* s1 */
+  sd   x10, 10*8(sp)  /* a0 */
+  sd   x11, 11*8(sp)  /* a1 */
+  sd   x12, 12*8(sp)  /* a2 */
+  sd   x13, 13*8(sp)  /* a3 */
+  sd   x14, 14*8(sp)  /* a4 */
+  sd   x15, 15*8(sp)  /* a5 */
+  sd   x16, 16*8(sp)  /* a6 */
+  sd   x17, 17*8(sp)  /* a7 */
+  sd   x18, 18*8(sp)  /* s2 */
+  sd   x19, 19*8(sp)  /* s3 */
+  sd   x20, 20*8(sp)  /* s4 */
+  sd   x21, 21*8(sp)  /* s5 */
+  sd   x22, 22*8(sp)  /* s6 */
+  sd   x23, 23*8(sp)  /* s7 */
+  sd   x24, 24*8(sp)  /* s8 */
+  sd   x25, 25*8(sp)  /* s9 */
+  sd   x26, 26*8(sp)  /* s10 */
+  sd   x27, 27*8(sp)  /* s11 */
+  sd   x28, 28*8(sp)  /* t3 */
+  sd   x29, 29*8(sp)  /* t4 */
+  sd   x30, 30*8(sp)  /* t5 */
+  sd   x31, 31*8(sp)  /* t6 */
+
+  csrr s0, mstatus
+  sd   s0,  32*8(sp)  /* mstatus */
+
+  addi s0, sp, XCPTCONTEXT_SIZE
+  sd   s0,  2*8(sp)   /* original SP */
+
+  /* Setup arg0(exeption cause), arg1(context) */
+
+  csrr a0, mcause  /* exception cause */
+  csrr s0, mepc
+  sd   s0, 0(sp)   /* exception PC */
+
+  mv   a1, sp      /* context = sp */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+  /* Switch to interrupt stack */
+
+  la   sp, g_intstackbase
+#endif
+
+  /* Call interrupt handler in C */
+
+  jal  x1, k210_dispatch_irq
+
+  /* If context switch is needed, return a new sp */
+
+  mv   sp, a0
+  ld   s0, 0(sp)    /* restore mepc */
+  csrw mepc, s0
+
+  ld   s0, 32*8(sp) /* restore mstatus */
+  csrw mstatus, s0
+
+  ld  x3,  3*8(sp)  /* gp */
+  ld  x4,  4*8(sp)  /* tp */
+  ld  x5,  5*8(sp)  /* t0 */
+  ld  x6,  6*8(sp)  /* t1 */
+  ld  x7,  7*8(sp)  /* t2 */
+  ld  x8,  8*8(sp)  /* s0 */
+  ld  x9,  9*8(sp)  /* s1 */
+  ld x10, 10*8(sp)  /* a0 */
+  ld x11, 11*8(sp)  /* a1 */
+  ld x12, 12*8(sp)  /* a2 */
+  ld x13, 13*8(sp)  /* a3 */
+  ld x14, 14*8(sp)  /* a4 */
+  ld x15, 15*8(sp)  /* a5 */
+  ld x16, 16*8(sp)  /* a6 */
+  ld x17, 17*8(sp)  /* a7 */
+  ld x18, 18*8(sp)  /* s2 */
+  ld x19, 19*8(sp)  /* s3 */
+  ld x20, 20*8(sp)  /* s4 */
+  ld x21, 21*8(sp)  /* s5 */
+  ld x22, 22*8(sp)  /* s6 */
+  ld x23, 23*8(sp)  /* s7 */
+  ld x24, 24*8(sp)  /* s8 */
+  ld x25, 25*8(sp)  /* s9 */
+  ld x26, 26*8(sp)  /* s10 */
+  ld x27, 27*8(sp)  /* s11 */
+  ld x28, 28*8(sp)  /* t3 */
+  ld x29, 29*8(sp)  /* t4 */
+  ld x30, 30*8(sp)  /* t5 */
+  ld x31, 31*8(sp)  /* t6 */
+
+  ld  x1,  1*8(sp)  /* ra */
+
+  ld  sp,  2*8(sp)  /* restore original sp */
+
+  /* Return from Machine Interrupt */
+
+  mret
+
+/************************************************************************************
+ *  Name: g_intstackalloc and g_intstackbase
+ ************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+  .bss
+  .align  8
+  .global g_intstackalloc
+  .global g_intstackbase
+  .type   g_intstackalloc, object
+  .type   g_intstackbase, object
+g_intstackalloc:
+  .skip  ((CONFIG_ARCH_INTERRUPTSTACK & ~7))
+g_intstackbase:
+  .skip  8
+  .size  g_intstackbase, 8
+  .size  g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~7)
+#endif
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/src/k210/k210_idle.c
similarity index 68%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to arch/risc-v/src/k210/k210_idle.c
index 6746e43..76919a5 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/src/k210/k210_idle.c
@@ -1,8 +1,10 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ *  arch/risc-v/src/k210/k210_idle.c
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
+ *
+ * Based on arch/risc-v/src/common/up_idle.c
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,36 +40,43 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
-
-#include <stdint.h>
-#include <debug.h>
-
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
 
-#include "up_arch.h"
+#include "up_internal.h"
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: modifyreg32
+ * Name: up_idle
  *
  * Description:
- *   Atomically modify the specified bits in a memory mapped register
+ *   up_idle() is the logic that will be executed when their is no other
+ *   ready-to-run task.  This is processor idle time and will continue until
+ *   some interrupt occurs to cause a context switch from the idle task.
+ *
+ *   Processing in this state may be processor-specific. e.g., this is where
+ *   power management operations might be performed.
  *
  ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
+void up_idle(void)
 {
-  irqstate_t flags;
-  uint32_t   regval;
+#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
+  /* If the system is idle and there are no timer interrupts, then process
+   * "fake" timer interrupts. Hopefully, something will wake up.
+   */
+
+  nxsched_process_timer();
+#else
+
+  /* This would be an appropriate place to put some MCU-specific logic to
+   * sleep in a reduced power mode until an interrupt occurs to save power
+   */
+
+  asm("WFI");
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
+#endif
 }
diff --git a/arch/risc-v/src/k210/k210_irq.c b/arch/risc-v/src/k210/k210_irq.c
new file mode 100644
index 0000000..4504196
--- /dev/null
+++ b/arch/risc-v/src/k210/k210_irq.c
@@ -0,0 +1,272 @@
+/****************************************************************************
+ * arch/risc-v/src/k210/k210_irq.c
+ *
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "k210.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_irqinitialize
+ ****************************************************************************/
+
+void up_irqinitialize(void)
+{
+  /* Disable Machine interrupts */
+
+  (void)up_irq_save();
+
+  /* Disable all global interrupts */
+
+  putreg32(0x0, K210_PLIC_ENABLE1);
+  putreg32(0x0, K210_PLIC_ENABLE2);
+
+  /* Clear pendings in PLIC */
+
+  uint32_t val = getreg32(K210_PLIC_CLAIM);
+  putreg32(val, K210_PLIC_CLAIM);
+
+  /* Colorize the interrupt stack for debug purposes */
+
+#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 7
+  size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~7);
+  up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size),
+                 intstack_size);
+#endif
+
+  /* Set priority for all global interrupts to 1 (lowest) */
+
+  int id;
+
+  for (id = 1; id <= 52; id++)
+    {
+      putreg32(1, (uintptr_t)K210_PLIC_PRIORITY + (4 * id));
+    }
+
+  /* Set irq threshold to 0 (permits all global interrupts) */
+
+  putreg32(0, K210_PLIC_THRESHOLD);
+
+  /* currents_regs is non-NULL only while processing an interrupt */
+
+  g_current_regs = NULL;
+
+  /* Attach the ecall interrupt handler */
+
+  irq_attach(K210_IRQ_ECALLM, up_swint, NULL);
+  up_enable_irq(K210_IRQ_ECALLM);
+
+#ifndef CONFIG_SUPPRESS_INTERRUPTS
+
+  /* And finally, enable interrupts */
+
+  (void)up_irq_enable();
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disable_irq
+ *
+ * Description:
+ *   Disable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_disable_irq(int irq)
+{
+  int extirq;
+  uint32_t oldstat;
+
+  if (irq == K210_IRQ_MTIMER)
+    {
+      /* Read mstatus & clear machine timer interrupt enable in mie */
+
+      asm volatile ("csrrc %0, mie, %1": "=r" (oldstat) : "r"(MIE_MTIE));
+    }
+  else if (irq > K210_IRQ_MEXT)
+    {
+      extirq = irq - K210_IRQ_MEXT;
+
+      /* Clear enable bit for the irq */
+
+      if (0 <= extirq && extirq <= 63)
+        {
+          modifyreg32(K210_PLIC_ENABLE1 + (4 * (extirq / 32)),
+                      1 << (extirq % 32), 0);
+        }
+      else
+        {
+          ASSERT(false);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: up_enable_irq
+ *
+ * Description:
+ *   Enable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_enable_irq(int irq)
+{
+  int extirq;
+  uint32_t oldstat;
+
+  if (irq == K210_IRQ_MTIMER)
+    {
+      /* Read mstatus & set machine timer interrupt enable in mie */
+
+      asm volatile ("csrrs %0, mie, %1": "=r" (oldstat) : "r"(MIE_MTIE));
+    }
+  else if (irq > K210_IRQ_MEXT)
+    {
+      extirq = irq - K210_IRQ_MEXT;
+
+      /* Set enable bit for the irq */
+
+      if (0 <= extirq && extirq <= 63)
+        {
+          modifyreg32(K210_PLIC_ENABLE1 + (4 * (extirq / 32)),
+                      0, 1 << (extirq % 32));
+        }
+      else
+        {
+          ASSERT(false);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: up_get_newintctx
+ *
+ * Description:
+ *   Return a value for EPIC. But K210 doesn't use EPIC for event control.
+ *
+ ****************************************************************************/
+
+uint32_t up_get_newintctx(void)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: up_ack_irq
+ *
+ * Description:
+ *   Acknowledge the IRQ
+ *
+ ****************************************************************************/
+
+void up_ack_irq(int irq)
+{
+}
+
+/****************************************************************************
+ * Name: up_irq_save
+ *
+ * Description:
+ *   Return the current interrupt state and disable interrupts
+ *
+ ****************************************************************************/
+
+irqstate_t up_irq_save(void)
+{
+  uint32_t oldstat;
+
+  /* Read mstatus & clear machine interrupt enable (MIE) in mstatus */
+
+  asm volatile ("csrrc %0, mstatus, %1": "=r" (oldstat) : "r"(MSTATUS_MIE));
+  return oldstat;
+}
+
+/****************************************************************************
+ * Name: up_irq_restore
+ *
+ * Description:
+ *   Restore previous IRQ mask state
+ *
+ ****************************************************************************/
+
+void up_irq_restore(irqstate_t flags)
+{
+  /* Machine mode - mstatus */
+
+  asm volatile("csrw mstatus, %0" : /* no output */ : "r" (flags));
+}
+
+/****************************************************************************
+ * Name: up_irq_enable
+ *
+ * Description:
+ *   Return the current interrupt state and enable interrupts
+ *
+ ****************************************************************************/
+
+irqstate_t up_irq_enable(void)
+{
+  uint32_t oldstat;
+
+#if 1
+  /* Enable MEIE (machine external interrupt enable) */
+
+  /* TODO: should move to up_enable_irq() */
+
+  asm volatile ("csrrs %0, mie, %1": "=r" (oldstat) : "r"(MIE_MEIE));
+#endif
+
+  /* Read mstatus & set machine interrupt enable (MIE) in mstatus */
+
+  asm volatile ("csrrs %0, mstatus, %1": "=r" (oldstat) : "r"(MSTATUS_MIE));
+  return oldstat;
+}
diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/src/k210/k210_irq_dispatch.c
similarity index 55%
copy from arch/risc-v/include/irq.h
copy to arch/risc-v/src/k210/k210_irq_dispatch.c
index 338b9a1..632affc 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/src/k210/k210_irq_dispatch.c
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/include/irq.h
+ * arch/risc-v/src/k210/k210_irq_dispatch.c
  *
- *   Copyright (C) 2016 Ken Pettit. All rights reserved.
- *   Author: Ken Pettit <pe...@gmail.com>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,41 +30,92 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through nuttx/irq.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_IRQ_H
-#define __ARCH_RISCV_INCLUDE_IRQ_H
-
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
-/* Include chip-specific IRQ definitions (including IRQ numbers) */
+#include <nuttx/config.h>
 
 #include <stdint.h>
+#include <assert.h>
+
 #include <nuttx/irq.h>
-#include <arch/chip/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+#include <arch/board/board.h>
 
-/* Include RISC-V architecture-specific IRQ definitions */
+#include "up_arch.h"
+#include "up_internal.h"
 
-#if defined(CONFIG_ARCH_RV32IM) || defined(CONFIG_ARCH_RV32I)
-#  include <arch/rv32im/irq.h>
-#endif
+#include "group/group.h"
 
 /****************************************************************************
- * Pre-processor Definitions
+ * Public Data
  ****************************************************************************/
 
-typedef uint32_t  irqstate_t;
+volatile uint64_t * g_current_regs;
 
 /****************************************************************************
- * Public Types
+ * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Public Variables
+ * k210_dispatch_irq
  ****************************************************************************/
 
-#endif /* __ARCH_RISCV_INCLUDE_IRQ_H */
+void *k210_dispatch_irq(uint64_t vector, uint64_t *regs)
+{
+  uint32_t  irq = (vector >> (27 + 32)) | (vector & 0xf);
+  uint64_t *mepc = regs;
+
+  if (K210_IRQ_MEXT == irq)
+    {
+      /* Read & write K210_PLIC_CLAIM to clear pending */
+
+      uint32_t val = getreg32(K210_PLIC_CLAIM);
+      putreg32(val, K210_PLIC_CLAIM);
+
+      irq += val;
+    }
+
+  /* NOTE: In case of ecall, we need to adjust mepc in the context */
+
+  if (K210_IRQ_ECALLM == irq)
+    {
+      *mepc += 4;
+    }
+
+#ifdef CONFIG_SUPPRESS_INTERRUPTS
+  PANIC();
+#else
+  /* Nested interrupts are not supported */
+
+  DEBUGASSERT(g_current_regs == NULL);
+
+  /* Current regs non-zero indicates that we are processing an interrupt;
+   * CURRENT_REGS is also used to manage interrupt level context switches.
+   */
+
+  g_current_regs = regs;
+
+  /* Deliver the IRQ */
+
+  irq_dispatch(irq, regs);
+#endif
+
+  /* If a context switch occurred while processing the interrupt then
+   * g_current_regs may have change value.  If we return any value different
+   * from the input regs, then the lower level will know that a context
+   * switch occurred during interrupt processing.
+   */
+
+  regs = (uint64_t *)g_current_regs;
+  g_current_regs = NULL;
+
+  /* Set machine previous privilege mode to machine mode */
+
+  *(regs + REG_INT_CTX_NDX) |= 0x3 << 11;
+
+  return regs;
+}
+
diff --git a/arch/risc-v/src/k210/k210_lowputc.c b/arch/risc-v/src/k210/k210_lowputc.c
new file mode 100644
index 0000000..8fba280
--- /dev/null
+++ b/arch/risc-v/src/k210/k210_lowputc.c
@@ -0,0 +1,140 @@
+/****************************************************************************
+ * arch/risc-v/src/k210/k210_lowputc.c
+ *
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "k210_config.h"
+#include "hardware/k210_memorymap.h"
+#include "hardware/k210_uart.h"
+#include "k210_clockconfig.h"
+#include "k210.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Select UART parameters for the selected console */
+
+#ifdef HAVE_SERIAL_CONSOLE
+#  if defined(CONFIG_UART0_SERIAL_CONSOLE)
+#    define K210_CONSOLE_BASE        K210_UART0_BASE
+#    define K210_CONSOLE_BAUD        CONFIG_UART0_BAUD
+#    define K210_CONSOLE_BITS        CONFIG_UART0_BITS
+#    define K210_CONSOLE_PARITY      CONFIG_UART0_PARITY
+#    define K210_CONSOLE_2STOP       CONFIG_UART0_2STOP
+#    define K210_CONSOLE_TX          GPIO_UART0_TX
+#    define K210_CONSOLE_RX          GPIO_UART0_RX
+#    define HAVE_UART
+#  elif defined(CONFIG_UART1_SERIAL_CONSOLE)
+#    define K210_CONSOLE_BASE        K210_UART1_BASE
+#    define K210_CONSOLE_BAUD        CONFIG_UART1_BAUD
+#    define K210_CONSOLE_BITS        CONFIG_UART1_BITS
+#    define K210_CONSOLE_PARITY      CONFIG_UART1_PARITY
+#    define K210_CONSOLE_2STOP       CONFIG_UART1_2STOP
+#    define K210_CONSOLE_TX          GPIO_UART1_TX
+#    define K210_CONSOLE_RX          GPIO_UART1_RX
+#    define HAVE_UART
+#  endif
+#endif /* HAVE_CONSOLE */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_lowputc
+ *
+ * Description:
+ *   Output one byte on the serial console
+ *
+ ****************************************************************************/
+
+void up_lowputc(char ch)
+{
+#ifdef HAVE_SERIAL_CONSOLE
+  /* Wait until the TX data register is empty */
+
+  while ((getreg32(K210_CONSOLE_BASE + UART_TXDATA_OFFSET) & UART_TX_FULL))
+    ;
+
+  /* Then send the character */
+
+  putreg32((uint32_t)ch, K210_CONSOLE_BASE + UART_TXDATA_OFFSET);
+
+#endif /* HAVE_CONSOLE */
+}
+
+/****************************************************************************
+ * Name: k210_lowsetup
+ *
+ * Description:
+ *   This performs basic initialization of the UART used for the serial
+ *   console.  Its purpose is to get the console output available as soon
+ *   as possible.
+ *
+ ****************************************************************************/
+
+void k210_lowsetup(void)
+{
+#if defined(HAVE_UART)
+
+  /* Enable and configure the selected console device */
+
+#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG)
+
+  /* Configure the UART Baud Rate */
+
+  uint32_t cpuclk = k210_get_cpuclk();
+  uint32_t div = (cpuclk / 115200) - 1;
+
+  putreg32(div, K210_CONSOLE_BASE + UART_DIV_OFFSET);
+
+  /* Enable TX */
+
+  putreg32(1, K210_CONSOLE_BASE + UART_TXCTL_OFFSET);
+#endif /* HAVE_SERIAL_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */
+#endif /* HAVE_UART */
+}
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/src/k210/k210_lowputc.h
similarity index 77%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to arch/risc-v/src/k210/k210_lowputc.h
index 6746e43..3403b1c 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/src/k210/k210_lowputc.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * arch/risc-v/src/k210/k210_lowputc.h
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,41 +33,43 @@
  *
  ****************************************************************************/
 
+#ifndef __ARCH_RISCV_SRC_K210_K210_LOWPUTC_H
+#define __ARCH_RISCV_SRC_K210_K210_LOWPUTC_H
+
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
 #include <nuttx/config.h>
 
-#include <stdint.h>
-#include <debug.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include "up_arch.h"
+#include "chip.h"
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
 /****************************************************************************
- * Name: modifyreg32
- *
- * Description:
- *   Atomically modify the specified bits in a memory mapped register
- *
+ * Name: k210_lowsetup
  ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
-{
-  irqstate_t flags;
-  uint32_t   regval;
+EXTERN void k210_lowsetup(void);
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
+#undef EXTERN
+#if defined(__cplusplus)
 }
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_SRC_K210_K210_LOWPUTC_H */
+
diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/src/k210/k210_memorymap.h
similarity index 64%
copy from arch/risc-v/include/irq.h
copy to arch/risc-v/src/k210/k210_memorymap.h
index 338b9a1..2c79271 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/src/k210/k210_memorymap.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/include/irq.h
+ * arch/risc-v/src/k210/k210_memorymap.h
  *
- *   Copyright (C) 2016 Ken Pettit. All rights reserved.
- *   Author: Ken Pettit <pe...@gmail.com>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,41 +30,32 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through nuttx/irq.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_IRQ_H
-#define __ARCH_RISCV_INCLUDE_IRQ_H
+#ifndef _ARCH_RISCV_SRC_K210_K210_MEMORYMAP_H
+#define _ARCH_RISCV_SRC_K210_K210_MEMORYMAP_H
 
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
-/* Include chip-specific IRQ definitions (including IRQ numbers) */
-
-#include <stdint.h>
-#include <nuttx/irq.h>
-#include <arch/chip/irq.h>
-
-/* Include RISC-V architecture-specific IRQ definitions */
-
-#if defined(CONFIG_ARCH_RV32IM) || defined(CONFIG_ARCH_RV32I)
-#  include <arch/rv32im/irq.h>
-#endif
+#include "hardware/k210_memorymap.h"
+#include "hardware/k210_uart.h"
+#include "hardware/k210_clint.h"
+#include "hardware/k210_plic.h"
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-typedef uint32_t  irqstate_t;
+/* Idle thread stack starts from _ebss */
 
-/****************************************************************************
- * Public Types
- ****************************************************************************/
+#ifndef __ASSEMBLY__
+#define K210_IDLESTACK_BASE  (uintptr_t)&_ebss
+#else
+#define K210_IDLESTACK_BASE  _ebss
+#endif
 
-/****************************************************************************
- * Public Variables
- ****************************************************************************/
+#define K210_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~7)
+#define K210_IDLESTACK_TOP  (K210_IDLESTACK_BASE + K210_IDLESTACK_SIZE)
+
+#endif  /* _ARCH_RISCV_SRC_K210_K210_MEMORYMAP_H */
 
-#endif /* __ARCH_RISCV_INCLUDE_IRQ_H */
diff --git a/arch/risc-v/src/k210/k210_serial.c b/arch/risc-v/src/k210/k210_serial.c
new file mode 100644
index 0000000..6d05e01
--- /dev/null
+++ b/arch/risc-v/src/k210/k210_serial.c
@@ -0,0 +1,745 @@
+/****************************************************************************
+ * arch/risc-v/src/k210/k210_serial.c
+ *
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "k210_config.h"
+#include "chip.h"
+#include "k210.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If we are not using the serial driver for the console, then we still must
+ * provide some minimal implementation of up_putc.
+ */
+
+#ifdef USE_SERIALDRIVER
+
+/* Which UART with be tty0/console and which tty1?  The console will always
+ * be ttyS0.  If there is no console then will use the lowest numbered UART.
+ */
+
+#ifdef HAVE_SERIAL_CONSOLE
+#  if defined(CONFIG_UART0_SERIAL_CONSOLE)
+#    define CONSOLE_DEV     g_uart0port     /* UART0 is console */
+#    define TTYS0_DEV       g_uart0port     /* UART0 is ttyS0 */
+#    undef  TTYS1_DEV                       /* No ttyS1 */
+#    define SERIAL_CONSOLE  1
+#  else
+#    error "I'm confused... Do we have a serial console or not?"
+#  endif
+#else
+#  undef  CONSOLE_DEV                        /* No console */
+#  undef  CONFIG_UART0_SERIAL_CONSOLE
+#  if defined(CONFIG_K210_UART0)
+#    define TTYS0_DEV       g_uart0port     /* UART0 is ttyS0 */
+#    undef  TTYS1_DEV                       /* No ttyS1 */
+#    define SERIAL_CONSOLE  1
+#  else
+#    undef  TTYS0_DEV
+#    undef  TTYS1_DEV
+#  endif
+#endif
+
+/* Common initialization logic will not not know that the all of the UARTs
+ * have been disabled.  So, as a result, we may still have to provide
+ * stub implementations of up_earlyserialinit(), up_serialinit(), and
+ * up_putc().
+ */
+
+#ifdef HAVE_UART_DEVICE
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct up_dev_s
+{
+  uintptr_t uartbase; /* Base address of UART registers */
+  uint32_t  baud;     /* Configured baud */
+  uint8_t   irq;      /* IRQ associated with this UART */
+  uint8_t   im;       /* Interrupt mask state */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Low-level helpers */
+
+static uint32_t up_serialin(struct up_dev_s *priv, int offset);
+static void up_serialout(struct up_dev_s *priv, int offset, uint32_t value);
+static void up_restoreuartint(struct up_dev_s *priv, uint8_t im);
+static void up_disableuartint(struct up_dev_s *priv, uint8_t *im);
+
+/* Serial driver methods */
+
+static int  up_setup(struct uart_dev_s *dev);
+static void up_shutdown(struct uart_dev_s *dev);
+static int  up_attach(struct uart_dev_s *dev);
+static void up_detach(struct uart_dev_s *dev);
+static int  up_interrupt(int irq, void *context, FAR void *arg);
+static int  up_ioctl(struct file *filep, int cmd, unsigned long arg);
+static int  up_receive(struct uart_dev_s *dev, uint32_t *status);
+static void up_rxint(struct uart_dev_s *dev, bool enable);
+static bool up_rxavailable(struct uart_dev_s *dev);
+static void up_send(struct uart_dev_s *dev, int ch);
+static void up_txint(struct uart_dev_s *dev, bool enable);
+static bool up_txready(struct uart_dev_s *dev);
+static bool up_txempty(struct uart_dev_s *dev);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct uart_ops_s g_uart_ops =
+{
+  .setup          = up_setup,
+  .shutdown       = up_shutdown,
+  .attach         = up_attach,
+  .detach         = up_detach,
+  .ioctl          = up_ioctl,
+  .receive        = up_receive,
+  .rxint          = up_rxint,
+  .rxavailable    = up_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol  = NULL,
+#endif
+  .send           = up_send,
+  .txint          = up_txint,
+  .txready        = up_txready,
+  .txempty        = up_txempty,
+};
+
+/* I/O buffers */
+
+#ifdef CONFIG_K210_UART0
+static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE];
+static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE];
+static uint32_t g_rxdata;
+#endif
+
+#ifdef CONFIG_K210_UART0
+static struct up_dev_s g_uart0priv =
+{
+  .uartbase  = K210_UART0_BASE,
+  .baud      = CONFIG_UART0_BAUD,
+  .irq       = K210_IRQ_UART0,
+};
+
+static uart_dev_t g_uart0port =
+{
+#if SERIAL_CONSOLE == 1
+  .isconsole = 1,
+#endif
+  .recv      =
+  {
+    .size    = CONFIG_UART0_RXBUFSIZE,
+    .buffer  = g_uart0rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART0_TXBUFSIZE,
+    .buffer  = g_uart0txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart0priv,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_serialin
+ ****************************************************************************/
+
+static uint32_t up_serialin(struct up_dev_s *priv, int offset)
+{
+  return getreg32(priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_serialout
+ ****************************************************************************/
+
+static void up_serialout(struct up_dev_s *priv, int offset, uint32_t value)
+{
+  putreg32(value, priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_restoreuartint
+ ****************************************************************************/
+
+static void up_restoreuartint(struct up_dev_s *priv, uint8_t im)
+{
+  irqstate_t flags = enter_critical_section();
+
+  priv->im = im;
+  up_serialout(priv, UART_IE_OFFSET, im);
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: up_disableuartint
+ ****************************************************************************/
+
+static void up_disableuartint(struct up_dev_s *priv, uint8_t *im)
+{
+  irqstate_t flags = enter_critical_section();
+
+  /* Return the current interrupt mask value */
+
+  if (im)
+    {
+     *im = priv->im;
+    }
+
+  /* Disable all interrupts */
+
+  priv->im = 0;
+  up_serialout(priv, UART_IE_OFFSET, 0);
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: up_setup
+ *
+ * Description:
+ *   Configure the UART baud, bits, parity, etc. This method is called the
+ *   first time that the serial port is opened.
+ *
+ ****************************************************************************/
+
+static int up_setup(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+#if 0 /* TODO: Setup divisor */
+#endif
+
+  /* Enable RX */
+
+  up_serialout(priv, UART_RXCTL_OFFSET, 1);
+
+  /* Set TX watermark level to 1 and enable TX */
+
+  up_serialout(priv, UART_TXCTL_OFFSET, 1 << 16 | 1);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_shutdown
+ *
+ * Description:
+ *   Disable the UART.  This method is called when the serial
+ *   port is closed
+ *
+ ****************************************************************************/
+
+static void up_shutdown(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(priv, NULL);
+}
+
+/****************************************************************************
+ * Name: up_attach
+ *
+ * Description:
+ *   Configure the UART to operation in interrupt driven mode.  This method is
+ *   called when the serial port is opened.  Normally, this is just after the
+ *   the setup() method is called, however, the serial console may operate in
+ *   a non-interrupt driven mode during the boot phase.
+ *
+ *   RX and TX interrupts are not enabled by the attach method (unless the
+ *   hardware supports multiple levels of interrupt enabling).  The RX and TX
+ *   interrupts are not enabled until the txint() and rxint() are called.
+ *
+ ****************************************************************************/
+
+static int up_attach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  int ret;
+
+  /* Initialize interrupt generation on the peripheral */
+
+  up_serialout(priv, UART_IE_OFFSET, UART_IE_TXWM | UART_IE_RXWM);
+
+  ret = irq_attach(priv->irq, up_interrupt, dev);
+
+  if (ret == OK)
+    {
+      /* Enable the interrupt (RX and TX interrupts are still disabled
+       * in the UART
+       */
+
+      up_enable_irq(priv->irq);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: up_detach
+ *
+ * Description:
+ *   Detach UART interrupts.  This method is called when the serial port is
+ *   closed normally just before the shutdown method is called.  The exception
+ *   is the serial console which is never shutdown.
+ *
+ ****************************************************************************/
+
+static void up_detach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disable_irq(priv->irq);
+
+  /* Detach from the interrupt */
+
+  irq_detach(priv->irq);
+}
+
+/****************************************************************************
+ * Name: up_interrupt
+ *
+ * Description:
+ *   This is the UART interrupt handler.  It will be invoked when an
+ *   interrupt received on the 'irq'  It should call uart_transmitchars or
+ *   uart_receivechar to perform the appropriate data transfers.  The
+ *   interrupt handling logic must be able to map the 'irq' number into the
+ *   approprite uart_dev_s structure in order to call these functions.
+ *
+ ****************************************************************************/
+
+static int up_interrupt(int irq, void *context, FAR void *arg)
+{
+  struct uart_dev_s *dev = (struct uart_dev_s *)arg;
+  struct up_dev_s   *priv;
+  uint32_t           status;
+  int                passes;
+
+  DEBUGASSERT(dev != NULL && dev->priv != NULL);
+  priv = (struct up_dev_s *)dev->priv;
+
+  /* Loop until there are no characters to be transferred or,
+   * until we have been looping for a long time.
+   */
+
+  for (passes = 0; passes < 256; passes++)
+    {
+      /* Retrieve interrupt pending status */
+
+      status = up_serialin(priv, UART_IP_OFFSET);
+
+      if (status == 0)
+        {
+          break;
+        }
+
+      if (status & UART_IP_RXWM)
+        {
+          /* Process incoming bytes */
+
+          uart_recvchars(dev);
+        }
+
+      if (status & UART_IP_TXWM)
+        {
+          /* Process outgoing bytes */
+
+          uart_xmitchars(dev);
+        }
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_ioctl
+ *
+ * Description:
+ *   All ioctl calls will be routed through this method
+ *
+ ****************************************************************************/
+
+static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: up_receive
+ *
+ * Description:
+ *   Called (usually) from the interrupt level to receive one
+ *   character from the UART.  Error bits associated with the
+ *   receipt are provided in the return 'status'.
+ *
+ ****************************************************************************/
+
+static int up_receive(struct uart_dev_s *dev, uint32_t *status)
+{
+  /* Return status information */
+
+  if (status)
+    {
+      *status = 0; /* We are not yet tracking serial errors */
+    }
+
+  /* Return cached data */
+
+  return g_rxdata;
+}
+
+/****************************************************************************
+ * Name: up_rxint
+ *
+ * Description:
+ *   Call to enable or disable RX interrupts
+ *
+ ****************************************************************************/
+
+static void up_rxint(struct uart_dev_s *dev, bool enable)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags = enter_critical_section();
+
+  if (enable)
+    {
+#ifndef CONFIG_SUPPRESS_SERIAL_INTS
+      priv->im |= UART_IE_RXWM;
+#endif
+    }
+  else
+    {
+      priv->im &= ~UART_IE_RXWM;
+    }
+
+  up_serialout(priv, UART_IE_OFFSET, priv->im);
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: up_rxavailable
+ *
+ * Description:
+ *   Return true if the receive register is not empty
+ *
+ ****************************************************************************/
+
+static bool up_rxavailable(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Return true is data is available in the receive data buffer */
+
+  uint32_t rxdata = up_serialin(priv, UART_RXDATA_OFFSET);
+
+  /* NOTE: In K210, actual data is also retrieved */
+
+  g_rxdata = rxdata & 0xff;
+
+  return (rxdata & UART_RX_EMPTY) == 0;
+}
+
+/****************************************************************************
+ * Name: up_send
+ *
+ * Description:
+ *   This method will send one byte on the UART.
+ *
+ ****************************************************************************/
+
+static void up_send(struct uart_dev_s *dev, int ch)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  up_serialout(priv, UART_TXDATA_OFFSET, (uint32_t)ch);
+}
+
+/****************************************************************************
+ * Name: up_txint
+ *
+ * Description:
+ *   Call to enable or disable TX interrupts
+ *
+ ****************************************************************************/
+
+static void up_txint(struct uart_dev_s *dev, bool enable)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+  if (enable)
+    {
+      /* Enable the TX interrupt */
+
+#ifndef CONFIG_SUPPRESS_SERIAL_INTS
+      priv->im |= UART_IE_TXWM;
+      up_serialout(priv, UART_IE_OFFSET, priv->im);
+
+      /* Fake a TX interrupt here by just calling uart_xmitchars() with
+       * interrupts disabled (note this may recurse).
+       */
+
+      uart_xmitchars(dev);
+#endif
+    }
+  else
+    {
+      /* Disable the TX interrupt */
+
+      priv->im &= ~UART_IE_TXWM;
+      up_serialout(priv, UART_IE_OFFSET, priv->im);
+    }
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: up_txready
+ *
+ * Description:
+ *   Return true if the tranmsit data register is not full
+ *
+ ****************************************************************************/
+
+static bool up_txready(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Return TRUE if the TX FIFO is not full */
+
+  return (up_serialin(priv, UART_TXDATA_OFFSET) & UART_TX_FULL) == 0;
+}
+
+/****************************************************************************
+ * Name: up_txempty
+ *
+ * Description:
+ *   Return true if the tranmsit data register is empty
+ *
+ ****************************************************************************/
+
+static bool up_txempty(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Return TRUE if the TX wartermak is pending */
+
+  return (up_serialin(priv, UART_IP_OFFSET) & UART_IP_TXWM) == 1;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_earlyserialinit
+ *
+ * Description:
+ *   Performs the low level UART initialization early in debug so that the
+ *   serial console will be available during bootup.  This must be called
+ *   before up_serialinit.  NOTE:  This function depends on GPIO pin
+ *   configuration performed in up_consoleinit() and main clock iniialization
+ *   performed in up_clkinitialize().
+ *
+ ****************************************************************************/
+
+void up_earlyserialinit(void)
+{
+  /* Disable interrupts from all UARTS.  The console is enabled in
+   * k210_consoleinit().
+   */
+
+  up_disableuartint(TTYS0_DEV.priv, NULL);
+#ifdef TTYS1_DEV
+  up_disableuartint(TTYS1_DEV.priv, NULL);
+#endif
+
+  /* Configuration whichever one is the console */
+
+#ifdef HAVE_SERIAL_CONSOLE
+  CONSOLE_DEV.isconsole = true;
+  up_setup(&CONSOLE_DEV);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_serialinit
+ *
+ * Description:
+ *   Register serial console and serial ports.  This assumes
+ *   that up_earlyserialinit was called previously.
+ *
+ ****************************************************************************/
+
+void up_serialinit(void)
+{
+  /* Register the console */
+
+#ifdef HAVE_SERIAL_CONSOLE
+  (void)uart_register("/dev/console", &CONSOLE_DEV);
+#endif
+
+  /* Register all UARTs */
+
+  (void)uart_register("/dev/ttyS0", &TTYS0_DEV);
+#ifdef TTYS1_DEV
+  (void)uart_register("/dev/ttyS1", &TTYS1_DEV);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_putc
+ *
+ * Description:
+ *   Provide priority, low-level access to support OS debug  writes
+ *
+ ****************************************************************************/
+
+int up_putc(int ch)
+{
+#ifdef HAVE_SERIAL_CONSOLE
+  struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv;
+  uint8_t imr;
+
+  up_disableuartint(priv, &imr);
+
+  /* Check for LF */
+
+  if (ch == '\n')
+    {
+      /* Add CR */
+
+      up_lowputc('\r');
+    }
+
+  up_lowputc(ch);
+  up_restoreuartint(priv, imr);
+#endif
+  return ch;
+}
+
+/****************************************************************************
+ * Name: up_earlyserialinit, up_serialinit, and up_putc
+ *
+ * Description:
+ *   stubs that may be needed.  These stubs would be used if all UARTs are
+ *   disabled.  In that case, the logic in common/up_initialize() is not
+ *   smart enough to know that there are not UARTs and will still expect
+ *   these interfaces to be provided.
+ *
+ ****************************************************************************/
+
+#else /* HAVE_UART_DEVICE */
+void up_earlyserialinit(void)
+{
+}
+
+void up_serialinit(void)
+{
+}
+
+int up_putc(int ch)
+{
+  return ch;
+}
+
+#endif /* HAVE_UART_DEVICE */
+#else /* USE_SERIALDRIVER */
+
+/****************************************************************************
+ * Name: up_putc
+ *
+ * Description:
+ *   Provide priority, low-level access to support OS debug writes
+ *
+ ****************************************************************************/
+
+int up_putc(int ch)
+{
+#ifdef HAVE_SERIAL_CONSOLE
+  /* Check for LF */
+
+  if (ch == '\n')
+    {
+      /* Add CR */
+
+      up_lowputc('\r');
+    }
+
+  up_lowputc(ch);
+#endif
+  return ch;
+}
+
+#endif /* USE_SERIALDRIVER */
+
diff --git a/arch/risc-v/include/syscall.h b/arch/risc-v/src/k210/k210_start.c
similarity index 53%
copy from arch/risc-v/include/syscall.h
copy to arch/risc-v/src/k210/k210_start.c
index 1616cb4..bdf7b89 100644
--- a/arch/risc-v/include/syscall.h
+++ b/arch/risc-v/src/k210/k210_start.c
@@ -1,10 +1,8 @@
 /****************************************************************************
- * arch/risc-v/include/syscall.h
+ * arch/risc-v/src/k210/k210_init.c
  *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- *   Modified 2016 by Ken Pettit for RISC-V architecture.
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -16,9 +14,6 @@
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -35,57 +30,104 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through include/syscall.h or include/sys/sycall.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_SYSCALL_H
-#define __ARCH_RISCV_INCLUDE_SYSCALL_H
-
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
-/* Include RISC-V architecture-specific syscall macros */
+#include <nuttx/config.h>
 
-#ifdef CONFIG_ARCH_RV32IM
-# include <arch/rv32im/syscall.h>
-#endif
+#include <arch/board/board.h>
+
+#include "k210_clockconfig.h"
+#include "k210.h"
+#include "chip.h"
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-/****************************************************************************
- * Public Types
- ****************************************************************************/
+#ifdef CONFIG_DEBUG_FEATURES
+#  define showprogress(c) up_lowputc(c)
+#else
+#  define showprogress(c)
+#endif
 
 /****************************************************************************
- * Inline functions
+ * Public Data
  ****************************************************************************/
 
+/* g_idle_topstack: _sbss is the start of the BSS region as defined by the
+ * linker script. _ebss lies at the end of the BSS region. The idle task
+ * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE.
+ * The IDLE thread is the thread that the system boots on and, eventually,
+ * becomes the IDLE, do nothing task that runs only when there is nothing
+ * else to run.  The heap continues from there until the end of memory.
+ * g_idle_topstack is a read-only variable the provides this computed
+ * address.
+ */
+
+uintptr_t g_idle_topstack = K210_IDLESTACK_TOP;
+
 /****************************************************************************
- * Public Data
+ * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Public Function Prototypes
+ * Name: k210_start
  ****************************************************************************/
 
-#ifndef __ASSEMBLY__
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C"
+void __k210_start(void)
 {
-#else
-#define EXTERN extern
-#endif
+  const uint32_t *src;
+  uint32_t *dest;
 
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
+  /* 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.
+   */
+
+  for (dest = &_sbss; dest < &_ebss; )
+    {
+      *dest++ = 0;
+    }
+
+  /* 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
+   * end of all of the other read-only data (.text, .rodata) at _eronly.
+   */
+
+  for (src = &_eronly, dest = &_sdata; dest < &_edata; )
+    {
+      *dest++ = *src++;
+    }
+
+  /* Setup PLL */
+
+  k210_clockconfig();
+
+  /* Configure the UART so we can get debug output */
+
+  k210_lowsetup();
+
+  showprogress('A');
+
+#ifdef USE_EARLYSERIALINIT
+  up_earlyserialinit();
 #endif
 
-#endif /* __ARCH_RISCV_INCLUDE_SYSCALL_H */
+  showprogress('B');
+
+  /* Do board initialization */
+
+  k210_boardinitialize();
+
+  showprogress('C');
 
+  /* Call nx_start() */
+
+  nx_start();
+
+  /* Shouldn't get here */
+
+  for (; ; );
+}
diff --git a/arch/risc-v/include/syscall.h b/arch/risc-v/src/k210/k210_timerisr.c
similarity index 57%
copy from arch/risc-v/include/syscall.h
copy to arch/risc-v/src/k210/k210_timerisr.c
index 1616cb4..80c3652 100644
--- a/arch/risc-v/include/syscall.h
+++ b/arch/risc-v/src/k210/k210_timerisr.c
@@ -1,10 +1,8 @@
 /****************************************************************************
- * arch/risc-v/include/syscall.h
+ * arch/risc-v/src/k210/k210_timerisr.c
  *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- *   Modified 2016 by Ken Pettit for RISC-V architecture.
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,57 +33,113 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through include/syscall.h or include/sys/sycall.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_SYSCALL_H
-#define __ARCH_RISCV_INCLUDE_SYSCALL_H
-
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
-/* Include RISC-V architecture-specific syscall macros */
+#include <nuttx/config.h>
 
-#ifdef CONFIG_ARCH_RV32IM
-# include <arch/rv32im/syscall.h>
-#endif
+#include <stdint.h>
+#include <time.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+
+#include "k210.h"
+#include "k210_clockconfig.h"
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
+#define getreg64(a)   (*(volatile uint64_t *)(a))
+#define putreg64(v,a) (*(volatile uint64_t *)(a) = (v))
+
+#define TICK_COUNT ((k210_get_cpuclk() / 50) / TICK_PER_SEC)
+
 /****************************************************************************
- * Public Types
+ * Private Data
  ****************************************************************************/
 
+static bool _b_tick_started = false;
+
 /****************************************************************************
- * Inline functions
+ * Private Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Public Data
+ * Name:  k210_reload_mtimecmp
  ****************************************************************************/
 
+static void k210_reload_mtimecmp(void)
+{
+  irqstate_t flags = spin_lock_irqsave();
+
+  uint64_t current;
+  uint64_t next;
+
+  if (!_b_tick_started)
+    {
+      _b_tick_started = true;
+      current = getreg64(K210_CLINT_MTIME);
+    }
+  else
+    {
+      current = getreg64(K210_CLINT_MTIMECMP);
+    }
+
+  uint64_t tick = TICK_COUNT;
+  next = current + tick;
+
+  putreg64(next, K210_CLINT_MTIMECMP);
+
+  spin_unlock_irqrestore(flags);
+}
+
 /****************************************************************************
- * Public Function Prototypes
+ * Name:  k210_timerisr
  ****************************************************************************/
 
-#ifndef __ASSEMBLY__
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C"
+static int k210_timerisr(int irq, void *context, FAR void *arg)
 {
-#else
-#define EXTERN extern
-#endif
+  k210_reload_mtimecmp();
 
-#undef EXTERN
-#ifdef __cplusplus
+  /* Process timer interrupt */
+
+  nxsched_process_timer();
+  return 0;
 }
-#endif
-#endif
 
-#endif /* __ARCH_RISCV_INCLUDE_SYSCALL_H */
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: riscv_timer_initialize
+ *
+ * Description:
+ *   This function is called during start-up to initialize
+ *   the timer interrupt.
+ *
+ ****************************************************************************/
+
+void riscv_timer_initialize(void)
+{
+#if 1
+  /* Attach timer interrupt handler */
+
+  (void)irq_attach(K210_IRQ_MTIMER, k210_timerisr, NULL);
+
+  /* Reload CLINT mtimecmp */
+
+  k210_reload_mtimecmp();
+
+  /* And enable the timer interrupt */
+
+  up_enable_irq(K210_IRQ_MTIMER);
+#endif
+}
 
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/src/k210/k210_vectors.S
similarity index 67%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to arch/risc-v/src/k210/k210_vectors.S
index 6746e43..e966c0b 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/src/k210/k210_vectors.S
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * arch/risc-v/src/k210/k210_vectors.S
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -14,9 +14,6 @@
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -31,43 +28,28 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- ****************************************************************************/
+ ************************************************************************************/
 
-/****************************************************************************
+/************************************************************************************
  * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdint.h>
-#include <debug.h>
+ ************************************************************************************/
 
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include "up_arch.h"
+  .section .text.vec
+  .global  __reset_vec
+  .global  __trap_vec
 
 /****************************************************************************
- * Public Functions
+ * Name: __reset_vec
  ****************************************************************************/
 
+__reset_vec:
+  jal  __start
+
 /****************************************************************************
- * Name: modifyreg32
- *
- * Description:
- *   Atomically modify the specified bits in a memory mapped register
- *
+ * Name: exception_common
  ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
-{
-  irqstate_t flags;
-  uint32_t   regval;
+__trap_vec:
+  j    exception_common
+  nop
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
-}
diff --git a/arch/risc-v/src/k210/up_schedulesigaction.c b/arch/risc-v/src/k210/up_schedulesigaction.c
new file mode 100644
index 0000000..2a3c2f4
--- /dev/null
+++ b/arch/risc-v/src/k210/up_schedulesigaction.c
@@ -0,0 +1,209 @@
+/****************************************************************************
+ * arch/risc-v/src/k210/up_schedulesigaction.c
+ *
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
+ *
+ * Based on arch/risc-v/src/nr5m100/up_schedulesigaction.c
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/k210/irq.h>
+
+#include "sched/sched.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_schedule_sigaction
+ *
+ * Description:
+ *   This function is called by the OS when one or more
+ *   signal handling actions have been queued for execution.
+ *   The architecture specific code must configure things so
+ *   that the 'igdeliver' callback is executed on the thread
+ *   specified by 'tcb' as soon as possible.
+ *
+ *   This function may be called from interrupt handling logic.
+ *
+ *   This operation should not cause the task to be unblocked
+ *   nor should it cause any immediate execution of sigdeliver.
+ *   Typically, a few cases need to be considered:
+ *
+ *   (1) This function may be called from an interrupt handler
+ *       During interrupt processing, all xcptcontext structures
+ *       should be valid for all tasks.  That structure should
+ *       be modified to invoke sigdeliver() either on return
+ *       from (this) interrupt or on some subsequent context
+ *       switch to the recipient task.
+ *   (2) If not in an interrupt handler and the tcb is NOT
+ *       the currently executing task, then again just modify
+ *       the saved xcptcontext structure for the recipient
+ *       task so it will invoke sigdeliver when that task is
+ *       later resumed.
+ *   (3) If not in an interrupt handler and the tcb IS the
+ *       currently executing task -- just call the signal
+ *       handler now.
+ *
+ ****************************************************************************/
+
+void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
+{
+  irqstate_t flags;
+  uint32_t int_ctx;
+
+  sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
+
+  /* Make sure that interrupts are disabled */
+
+  flags = enter_critical_section();
+
+  /* Refuse to handle nested signal actions */
+
+  if (!tcb->xcp.sigdeliver)
+    {
+      /* First, handle some special cases when the signal is
+       * being delivered to the currently executing task.
+       */
+
+      sinfo("rtcb=0x%p g_current_regs=0x%p\n",
+            this_task(), g_current_regs);
+
+      if (tcb == this_task())
+        {
+          /* CASE 1:  We are not in an interrupt handler and
+           * a task is signalling itself for some reason.
+           */
+
+          if (!g_current_regs)
+            {
+              /* In this case just deliver the signal now. */
+
+              sigdeliver(tcb);
+            }
+
+          /* CASE 2:  We are in an interrupt handler AND the
+           * interrupted task is the same as the one that
+           * must receive the signal, then we will have to modify
+           * the return state as well as the state in the TCB.
+           *
+           * Hmmm... there looks like a latent bug here: The following
+           * logic would fail in the strange case where we are in an
+           * interrupt handler, the thread is signalling itself, but
+           * a context switch to another task has occurred so that
+           * g_current_regs does not refer to the thread of this_task()!
+           */
+
+          else
+            {
+              /* Save the return EPC and STATUS registers.  These will be
+               * restored by the signal trampoline after the signals have
+               * been delivered.
+               */
+
+              tcb->xcp.sigdeliver       = sigdeliver;
+              tcb->xcp.saved_epc        = g_current_regs[REG_EPC];
+              tcb->xcp.saved_int_ctx    = g_current_regs[REG_INT_CTX];
+
+              /* Then set up to vector to the trampoline with interrupts
+               * disabled
+               */
+
+              g_current_regs[REG_EPC]     = (uintptr_t)up_sigdeliver;
+
+              int_ctx                     = g_current_regs[REG_INT_CTX];
+              int_ctx                    &= ~MSTATUS_MIE;
+
+              g_current_regs[REG_INT_CTX] = int_ctx;
+
+              /* And make sure that the saved context in the TCB
+               * is the same as the interrupt return context.
+               */
+
+              up_savestate(tcb->xcp.regs);
+
+              sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n",
+                    tcb->xcp.saved_epc, tcb->xcp.saved_status,
+                    g_current_regs[REG_EPC], g_current_regs[REG_INT_CTX]);
+            }
+        }
+
+      /* Otherwise, we are (1) signaling a task is not running
+       * from an interrupt handler or (2) we are not in an
+       * interrupt handler and the running task is signalling
+       * some non-running task.
+       */
+
+      else
+        {
+          /* Save the return EPC and STATUS registers.  These will be
+           * restored by the signal trampoline after the signals have
+           * been delivered.
+           */
+
+          tcb->xcp.sigdeliver       = sigdeliver;
+          tcb->xcp.saved_epc        = tcb->xcp.regs[REG_EPC];
+          tcb->xcp.saved_int_ctx    = tcb->xcp.regs[REG_INT_CTX];
+
+          /* Then set up to vector to the trampoline with interrupts
+           * disabled
+           */
+
+          tcb->xcp.regs[REG_EPC]      = (uintptr_t)up_sigdeliver;
+
+          int_ctx                     = tcb->xcp.regs[REG_INT_CTX];
+          int_ctx                    &= ~MSTATUS_MIE;
+
+          tcb->xcp.regs[REG_INT_CTX]  = int_ctx;
+
+          sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n",
+                tcb->xcp.saved_epc, tcb->xcp.saved_status,
+                tcb->xcp.regs[REG_EPC], tcb->xcp.regs[REG_INT_CTX]);
+        }
+    }
+
+  leave_critical_section(flags);
+}
diff --git a/arch/risc-v/src/rv64gc/Kconfig b/arch/risc-v/src/rv64gc/Kconfig
new file mode 100644
index 0000000..58e164c
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/Kconfig
@@ -0,0 +1,29 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+comment "RV64GC Configuration Options"
+
+choice
+	prompt "Toolchain Selection"
+	default RV64GC_TOOLCHAIN_GNU_RVGW if TOOLCHAIN_WINDOWS
+	default RV64GC_TOOLCHAIN_GNU_RVGL if !TOOLCHAIN_WINDOWS
+
+config RV64GC_TOOLCHAIN_GNU_RVGL
+	bool "Generic GNU RVG toolchain under Linux (or other POSIX environment)"
+	select ARCH_TOOLCHAIN_GNU
+	---help---
+		This option should work for any modern GNU toolchain (GCC 5.2 or newer)
+		configured for riscv64-unknown-elf.
+
+config RV64GC_TOOLCHAIN_GNU_RVGW
+	bool "Generic GNU RVG toolchain under Windows"
+	select ARCH_TOOLCHAIN_GNU
+	depends on TOOLCHAIN_WINDOWS
+	---help---
+		This option should work for any modern GNU toolchain (GCC 5.2 or newer)
+		configured for riscv64-unknown-elf.
+
+endchoice
+
diff --git a/arch/risc-v/src/rv64gc/Toolchain.defs b/arch/risc-v/src/rv64gc/Toolchain.defs
new file mode 100644
index 0000000..dbca46b
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/Toolchain.defs
@@ -0,0 +1,93 @@
+############################################################################
+# arch/risc-v/src/rv64gc/Toolchain.defs
+#
+#   Copyright (C) 2012-2013, 2015 Gregory Nutt. All rights reserved.
+#   Author: Gregory Nutt <gn...@nuttx.org>
+#
+#   modified for RISC-V:
+#
+#   Copyright (C) 2016 Ken Pettit. All rights reserved.
+#   Author: Ken Pettit <pe...@gmail.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+# Setup for the selected toolchain
+
+#
+# Handle old-style chip-specific toolchain names in the absence of
+# a new-style toolchain specification, force the selection of a single
+# toolchain and allow the selected toolchain to be overridden by a
+# command-line selection.
+#
+
+ifeq ($(filter y, $(CONFIG_RV64GC_TOOLCHAIN_GNU_RVGL)),y)
+  CONFIG_RISCV_TOOLCHAIN ?= GNU_RVGL
+endif
+
+ifeq ($(filter y, $(CONFIG_RV64GC_TOOLCHAIN_GNU_RVGW)),y)
+  CONFIG_RISCV_TOOLCHAIN ?= GNU_RVGW
+endif
+
+#
+# Supported toolchains
+#
+# Each toolchain definition should set:
+#
+#  CROSSDEV         The GNU toolchain triple (command prefix)
+#  ARCROSSDEV       If required, an alternative prefix used when
+#                   invoking ar and nm.
+#  ARCHCPUFLAGS     CPU-specific flags selecting the instruction set
+#                   options, etc.
+#  MAXOPTIMIZATION  The maximum optimization level that results in
+#                   reliable code generation.
+#
+
+ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y)
+  MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL)
+endif
+
+# Generic GNU RVG toolchain on OS X, Linux or any typical Posix system
+
+ifeq ($(CONFIG_RISCV_TOOLCHAIN),GNU_RVGL)
+  CROSSDEV ?= riscv64-unknown-elf-
+  ARCROSSDEV ?= riscv64-unknown-elf-
+endif
+
+ifeq ($(CONFIG_RISCV_TOOLCHAIN),GNU_RVGW)
+  CROSSDEV ?= riscv32-unknown-elf-
+  ARCROSSDEV ?= riscv32-unknown-elf-
+  ifneq ($(CONFIG_WINDOWS_NATIVE),y)
+    WINTOOL = y
+  endif
+endif
+
+# Individual tools may limit the optimization level but, by default, the
+# optimization level will be set to -Os
+
+ifeq ($(CONFIG_DEBUG_SYMBOLS),)
+MAXOPTIMIZATION ?= -Os
+endif
diff --git a/arch/risc-v/src/rv64gc/up_assert.c b/arch/risc-v/src/rv64gc/up_assert.c
new file mode 100644
index 0000000..e9c3871
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/up_assert.c
@@ -0,0 +1,411 @@
+/****************************************************************************
+ * arch/risc-v/src/rv64gc/up_assert.c
+ *
+ *   Copyright (C) 2011-2015, 2018 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+#include <nuttx/syslog/syslog.h>
+#include <nuttx/usb/usbdev_trace.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "sched/sched.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* USB trace dumping */
+
+#ifndef CONFIG_USBDEV_TRACE
+#  undef CONFIG_ARCH_USBDUMP
+#endif
+
+#ifndef CONFIG_BOARD_RESET_ON_ASSERT
+#  define CONFIG_BOARD_RESET_ON_ASSERT 0
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_STACKDUMP
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_getsp
+ ****************************************************************************/
+
+static inline uint64_t up_getsp(void)
+{
+  register uint64_t sp;
+  __asm__
+  (
+    "\tadd  %0, x0, x2\n"
+    : "=r"(sp)
+  );
+  return sp;
+}
+
+/****************************************************************************
+ * Name: up_stackdump
+ ****************************************************************************/
+
+static void up_stackdump(uint64_t sp, uintptr_t stack_base)
+{
+  uintptr_t stack;
+
+  for (stack = sp & ~0x1f; stack < stack_base; stack += 32)
+    {
+      uint32_t *ptr = (uint32_t *)stack;
+      _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+             stack, ptr[0], ptr[1], ptr[2], ptr[3],
+             ptr[4], ptr[5], ptr[6], ptr[7]);
+    }
+}
+
+/****************************************************************************
+ * Name: up_taskdump
+ ****************************************************************************/
+
+#ifdef CONFIG_STACK_COLORATION
+static void up_taskdump(FAR struct tcb_s *tcb, FAR void *arg)
+{
+  /* Dump interesting properties of this task */
+
+#if CONFIG_TASK_NAME_SIZE > 0
+  _alert("%s: PID=%d Stack Used=%lu of %lu\n",
+        tcb->name, tcb->pid, (unsigned long)up_check_tcbstack(tcb),
+        (unsigned long)tcb->adj_stack_size);
+#else
+  _alert("PID: %d Stack Used=%lu of %lu\n",
+        tcb->pid, (unsigned long)up_check_tcbstack(tcb),
+        (unsigned long)tcb->adj_stack_size);
+#endif
+}
+#endif
+
+/****************************************************************************
+ * Name: up_showtasks
+ ****************************************************************************/
+
+#ifdef CONFIG_STACK_COLORATION
+static inline void up_showtasks(void)
+{
+  /* Dump interesting properties of each task in the crash environment */
+
+  sched_foreach(up_taskdump, NULL);
+}
+#else
+#  define up_showtasks()
+#endif
+
+/****************************************************************************
+ * Name: up_registerdump
+ ****************************************************************************/
+
+static inline void up_registerdump(void)
+{
+  /* Are user registers available from interrupt processing? */
+
+  if (g_current_regs)
+    {
+      _alert("EPC:%016x \n",
+             g_current_regs[REG_EPC]);
+
+      _alert("A0:%016x A1:%016x A2:%016x A3:%016x \n",
+             g_current_regs[REG_A0], g_current_regs[REG_A1],
+             g_current_regs[REG_A2], g_current_regs[REG_A3]);
+
+      _alert("A4:%016x A5:%016x A6:%016x A7:%016x \n",
+             g_current_regs[REG_A4], g_current_regs[REG_A5],
+             g_current_regs[REG_A6], g_current_regs[REG_A7]);
+
+      _alert("T0:%016x T1:%016x T2:%016x T3:%016x \n",
+             g_current_regs[REG_T0], g_current_regs[REG_T1],
+             g_current_regs[REG_T2], g_current_regs[REG_T3]);
+
+      _alert("T4:%016x T5:%016x T6:%016x \n",
+             g_current_regs[REG_T4], g_current_regs[REG_T5],
+             g_current_regs[REG_T6]);
+
+      _alert("S0:%016x S1:%016x S2:%016x S3:%016x \n",
+             g_current_regs[REG_S0], g_current_regs[REG_S1],
+             g_current_regs[REG_S2], g_current_regs[REG_S3]);
+
+      _alert("S4:%016x S5:%016x S6:%016x S7:%016x \n",
+             g_current_regs[REG_S4], g_current_regs[REG_S5],
+             g_current_regs[REG_S6], g_current_regs[REG_S7]);
+
+      _alert("S8:%016x S9:%016x S10:%016x S11:%016x \n",
+             g_current_regs[REG_S8], g_current_regs[REG_S9],
+             g_current_regs[REG_S10], g_current_regs[REG_S11]);
+
+#ifdef RISCV_SAVE_GP
+      _alert("GP:%016x SP:%016x FP:%016x TP:%016x RA:%016x \n",
+             g_current_regs[REG_GP], g_current_regs[REG_SP],
+             g_current_regs[REG_FP], g_current_regs[REG_TP],
+             g_current_regs[REG_RA]);
+#else
+      _alert("SP:%016x FP:%016x TP:%016x RA:%016x \n",
+             g_current_regs[REG_SP], g_current_regs[REG_FP],
+             g_current_regs[REG_TP], g_current_regs[REG_RA]);
+#endif
+    }
+}
+
+/****************************************************************************
+ * Name: up_dumpstate
+ ****************************************************************************/
+
+static void up_dumpstate(void)
+{
+  struct tcb_s *rtcb = running_task();
+  uint64_t sp = up_getsp();
+  uintptr_t ustackbase;
+  uintptr_t ustacksize;
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+  uintptr_t istackbase;
+  uintptr_t istacksize;
+#endif
+
+  /* Dump the registers (if available) */
+
+  up_registerdump();
+
+  /* Get the limits on the user stack memory */
+
+  if (rtcb->pid == 0) /* Check for CPU0 IDLE thread */
+    {
+      ustackbase = g_idle_topstack - 8;
+      ustacksize = CONFIG_IDLETHREAD_STACKSIZE;
+    }
+  else
+    {
+      ustackbase = (uintptr_t)rtcb->adj_stack_ptr;
+      ustacksize = (uintptr_t)rtcb->adj_stack_size;
+    }
+
+  /* Get the limits on the interrupt stack memory */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+  istackbase = (uintptr_t)&g_intstackbase;
+  istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~7) - 8;
+
+  /* Show interrupt stack info */
+
+  _alert("sp:     %016x\n", sp);
+  _alert("IRQ stack:\n");
+  _alert("  base: %016x\n", istackbase);
+  _alert("  size: %016x\n", istacksize);
+
+  /* Does the current stack pointer lie within the interrupt
+   * stack?
+   */
+
+  if (sp <= istackbase && sp > istackbase - istacksize)
+    {
+      /* Yes.. dump the interrupt stack */
+
+      up_stackdump(sp, istackbase);
+
+      /* Extract the user stack pointer */
+
+      sp = g_current_regs[REG_SP];
+      _alert("sp:     %016x\n", sp);
+    }
+  else if (g_current_regs)
+    {
+      _alert("ERROR: Stack pointer is not within the interrupt stack\n");
+      up_stackdump(istackbase - istacksize, istackbase);
+    }
+
+  /* Show user stack info */
+
+  _alert("User stack:\n");
+  _alert("  base: %016x\n", ustackbase);
+  _alert("  size: %016x\n", ustacksize);
+#else
+  _alert("sp:         %016x\n", sp);
+  _alert("stack base: %016x\n", ustackbase);
+  _alert("stack size: %016x\n", ustacksize);
+#endif
+
+  /* Dump the user stack if the stack pointer lies within the allocated user
+   * stack memory.
+   */
+
+  if (sp > ustackbase || sp <= ustackbase - ustacksize)
+    {
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase - ustacksize, ustackbase);
+    }
+  else
+    {
+      up_stackdump(sp, ustackbase);
+    }
+}
+
+#endif /* CONFIG_ARCH_STACKDUMP */
+
+/****************************************************************************
+ * Name: _up_assert
+ ****************************************************************************/
+
+static void _up_assert(int errorcode) noreturn_function;
+static void _up_assert(int errorcode)
+{
+  /* Flush any buffered SYSLOG data */
+
+  (void)syslog_flush();
+
+  /* Are we in an interrupt handler or the idle task? */
+
+  if (g_current_regs || running_task()->flink == NULL)
+    {
+      (void)up_irq_save();
+      for (; ; )
+        {
+#if CONFIG_BOARD_RESET_ON_ASSERT >= 1
+          board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE);
+#endif
+#ifdef CONFIG_ARCH_LEDS
+          board_autoled_on(LED_PANIC);
+          up_mdelay(250);
+          board_autoled_off(LED_PANIC);
+          up_mdelay(250);
+#endif
+        }
+    }
+  else
+    {
+#if CONFIG_BOARD_RESET_ON_ASSERT >= 2
+      board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE);
+#endif
+      exit(errorcode);
+    }
+}
+
+/****************************************************************************
+ * Name: assert_tracecallback
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_USBDUMP
+static int usbtrace_syslog(FAR const char *fmt, ...)
+{
+  va_list ap;
+  int ret;
+
+  /* Let nx_vsyslog do the real work */
+
+  va_start(ap, fmt);
+  ret = nx_vsyslog(LOG_EMERG, fmt, &ap);
+  va_end(ap);
+  return ret;
+}
+
+static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg)
+{
+  usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value);
+  return 0;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_assert
+ ****************************************************************************/
+
+void up_assert(const uint8_t *filename, int lineno)
+{
+#if CONFIG_TASK_NAME_SIZE > 0 && defined(CONFIG_DEBUG_ALERT)
+  struct tcb_s *rtcb = running_task();
+#endif
+
+  board_autoled_on(LED_ASSERTION);
+
+  /* Flush any buffered SYSLOG data (from prior to the assertion) */
+
+  (void)syslog_flush();
+
+#if CONFIG_TASK_NAME_SIZE > 0
+  _alert("Assertion failed at file:%s line: %d task: %s\n",
+        filename, lineno, rtcb->name);
+#else
+  _alert("Assertion failed at file:%s line: %d\n",
+        filename, lineno);
+#endif
+
+  up_dumpstate();
+
+  /* Dump the state of all tasks (if available) */
+
+  up_showtasks();
+
+#ifdef CONFIG_ARCH_USBDUMP
+  /* Dump USB trace data */
+
+  (void)usbtrace_enumerate(assert_tracecallback, NULL);
+#endif
+
+  /* Flush any buffered SYSLOG data (from the above) */
+
+  (void)syslog_flush();
+
+#ifdef CONFIG_BOARD_CRASHDUMP
+  board_crashdump(up_getsp(), running_task(), filename, lineno);
+#endif
+
+  _up_assert(EXIT_FAILURE);
+}
diff --git a/arch/risc-v/src/rv64gc/up_blocktask.c b/arch/risc-v/src/rv64gc/up_blocktask.c
new file mode 100644
index 0000000..2c0d7f7
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/up_blocktask.c
@@ -0,0 +1,179 @@
+/****************************************************************************
+ * arch/risc-v/src/rv64gc/up_blocktask.c
+ *
+ *   Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <sched.h>
+#include <syscall.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/sched.h>
+
+#include "sched/sched.h"
+#include "group/group.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_block_task
+ *
+ * Description:
+ *   The currently executing task at the head of
+ *   the ready to run list must be stopped.  Save its context
+ *   and move it to the inactive list specified by task_state.
+ *
+ * Input Parameters:
+ *   tcb: Refers to a task in the ready-to-run list (normally
+ *     the task at the head of the list).  It most be
+ *     stopped, its context saved and moved into one of the
+ *     waiting task lists.  It it was the task at the head
+ *     of the ready-to-run list, then a context to the new
+ *     ready to run task must be performed.
+ *   task_state: Specifies which waiting task list should be
+ *     hold the blocked task TCB.
+ *
+ ****************************************************************************/
+
+void up_block_task(struct tcb_s *tcb, tstate_t task_state)
+{
+  struct tcb_s *rtcb = this_task();
+  bool switch_needed;
+
+  /* Verify that the context switch can be performed */
+
+  DEBUGASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
+              (tcb->task_state <= LAST_READY_TO_RUN_STATE));
+
+  /* Remove the tcb task from the ready-to-run list.  If we
+   * are blocking the task at the head of the task list (the
+   * most likely case), then a context switch to the next
+   * ready-to-run task is needed. In this case, it should
+   * also be true that rtcb == tcb.
+   */
+
+  switch_needed = sched_removereadytorun(tcb);
+
+  /* Add the task to the specified blocked task list */
+
+  sched_addblocked(tcb, (tstate_t)task_state);
+
+  /* If there are any pending tasks, then add them to the ready-to-run
+   * task list now
+   */
+
+  if (g_pendingtasks.head)
+    {
+      switch_needed |= sched_mergepending();
+    }
+
+  /* Now, perform the context switch if one is needed */
+
+  if (switch_needed)
+    {
+      /* Update scheduler parameters */
+
+      sched_suspend_scheduler(rtcb);
+
+      /* Are we in an interrupt handler? */
+
+      if (g_current_regs)
+        {
+          /* Yes, then we have to do things differently.
+           * Just copy the g_current_regs into the OLD rtcb.
+           */
+
+          up_savestate(rtcb->xcp.regs);
+
+          /* Restore the exception context of the rtcb at the (new) head
+           * of the ready-to-run task list.
+           */
+
+          rtcb = this_task();
+
+          /* Reset scheduler parameters */
+
+          sched_resume_scheduler(rtcb);
+
+          /* Then switch contexts.  Any necessary address environment
+           * changes will be made when the interrupt returns.
+           */
+
+          up_restorestate(rtcb->xcp.regs);
+        }
+
+      /* No, then we will need to perform the user context switch */
+
+      else
+        {
+          /* Get the context of the task at the head of the ready to
+           * run list.
+           */
+
+          struct tcb_s *nexttcb = this_task();
+
+#ifdef CONFIG_ARCH_ADDRENV
+          /* Make sure that the address environment for the previously
+           * running task is closed down gracefully (data caches dump,
+           * MMU flushed) and set up the address environment for the new
+           * thread at the head of the ready-to-run list.
+           */
+
+          (void)group_addrenv(nexttcb);
+#endif
+          /* Reset scheduler parameters */
+
+          sched_resume_scheduler(nexttcb);
+
+          /* Then switch contexts */
+
+          up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+
+          /* up_switchcontext forces a context switch to the task at the
+           * head of the ready-to-run list.  It does not 'return' in the
+           * normal sense.  When it does return, it is because the blocked
+           * task is again ready to run and has execution priority.
+           */
+        }
+    }
+}
diff --git a/arch/risc-v/include/syscall.h b/arch/risc-v/src/rv64gc/up_copystate.c
similarity index 79%
copy from arch/risc-v/include/syscall.h
copy to arch/risc-v/src/rv64gc/up_copystate.c
index 1616cb4..9470777 100644
--- a/arch/risc-v/include/syscall.h
+++ b/arch/risc-v/src/rv64gc/up_copystate.c
@@ -1,11 +1,9 @@
 /****************************************************************************
- * arch/risc-v/include/syscall.h
+ * arch/risc-v/src/rv64gc/up_copystate.c
  *
  *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
  *
- *   Modified 2016 by Ken Pettit for RISC-V architecture.
- *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -35,57 +33,54 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through include/syscall.h or include/sys/sycall.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_SYSCALL_H
-#define __ARCH_RISCV_INCLUDE_SYSCALL_H
-
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
-/* Include RISC-V architecture-specific syscall macros */
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <arch/irq.h>
 
-#ifdef CONFIG_ARCH_RV32IM
-# include <arch/rv32im/syscall.h>
-#endif
+#include "up_internal.h"
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
 /****************************************************************************
- * Public Types
+ * Private Data
  ****************************************************************************/
 
 /****************************************************************************
- * Inline functions
+ * Private Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Public Data
+ * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Public Function Prototypes
+ * Name: up_copystate
  ****************************************************************************/
 
-#ifndef __ASSEMBLY__
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C"
+/* A little faster than most memcpy's */
+
+void up_copystate(uint64_t *dest, uint64_t *src)
 {
-#else
-#define EXTERN extern
-#endif
+  int i;
 
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
-#endif
+  /* In the RISC-V model, the state is copied from the stack to the TCB,
+   * but only a reference is passed to get the state from the TCB.  So the
+   * following check avoids copying the TCB save area onto itself:
+   */
 
-#endif /* __ARCH_RISCV_INCLUDE_SYSCALL_H */
+  if (src != dest)
+    {
+      for (i = 0; i < XCPTCONTEXT_REGS; i++)
+        {
+          *dest++ = *src++;
+        }
+    }
+}
 
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/arch/risc-v/src/rv64gc/up_initialstate.c
similarity index 54%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to arch/risc-v/src/rv64gc/up_initialstate.c
index 6746e43..039631f 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/arch/risc-v/src/rv64gc/up_initialstate.c
@@ -1,7 +1,7 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * arch/risc-v/src/rv64gc/up_initialstate.c
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,12 +39,14 @@
 
 #include <nuttx/config.h>
 
+#include <sys/types.h>
 #include <stdint.h>
-#include <debug.h>
+#include <string.h>
 
-#include <nuttx/irq.h>
 #include <nuttx/arch.h>
+#include <arch/irq.h>
 
+#include "up_internal.h"
 #include "up_arch.h"
 
 /****************************************************************************
@@ -52,22 +54,68 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: modifyreg32
+ * Name: up_initial_state
  *
  * Description:
- *   Atomically modify the specified bits in a memory mapped register
+ *   A new thread is being started and a new TCB
+ *   has been created. This function is called to initialize
+ *   the processor specific portions of the new TCB.
+ *
+ *   This function must setup the initial architecture registers
+ *   and/or  stack so that execution will begin at tcb->start
+ *   on the next context switch.
  *
  ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
+void up_initial_state(struct tcb_s *tcb)
 {
-  irqstate_t flags;
-  uint32_t   regval;
-
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
+  struct xcptcontext *xcp = &tcb->xcp;
+  uint32_t regval;
+
+  /* Initialize the initial exception register context structure */
+
+  memset(xcp, 0, sizeof(struct xcptcontext));
+
+  /* Save the initial stack pointer.  Hmmm.. the stack is set to the very
+   * beginning of the stack region.  Some functions may want to store data on
+   * the caller's stack and it might be good to reserve some space.  However,
+   * only the start function would do that and we have control over that one
+   */
+
+  xcp->regs[REG_SP]      = (uintptr_t)tcb->adj_stack_ptr;
+
+  /* Save the task entry point */
+
+  xcp->regs[REG_EPC]     = (uintptr_t)tcb->start;
+
+  /* If this task is running PIC, then set the PIC base register to the
+   * address of the allocated D-Space region.
+   */
+
+#ifdef CONFIG_PIC
+#  warning "Missing logic"
+#endif
+
+  /* Set privileged- or unprivileged-mode, depending on how NuttX is
+   * configured and what kind of thread is being started.
+   *
+   * If the kernel build is not selected, then all threads run in
+   * privileged thread mode.
+   */
+
+#ifdef CONFIG_BUILD_KERNEL
+#  warning "Missing logic"
+#endif
+
+  /* Set the initial value of the interrupt context register.
+   *
+   * Since various RISC-V platforms use different interrupt
+   * methodologies, the value of the interrupt context is
+   * part specific.
+   *
+   */
+
+  regval = up_get_newintctx();
+  xcp->regs[REG_INT_CTX] = regval;
 }
+
diff --git a/arch/risc-v/src/rv64gc/up_releasepending.c b/arch/risc-v/src/rv64gc/up_releasepending.c
new file mode 100644
index 0000000..367a1d5
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/up_releasepending.c
@@ -0,0 +1,149 @@
+/****************************************************************************
+ *  arch/risc-v/src/rv64gc/up_releasepending.c
+ *
+ *   Copyright (C) 2011, 2014-2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <syscall.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/sched.h>
+
+#include "sched/sched.h"
+#include "group/group.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_release_pending
+ *
+ * Description:
+ *   Release and ready-to-run tasks that have
+ *   collected in the pending task list.  This can call a
+ *   context switch if a new task is placed at the head of
+ *   the ready to run list.
+ *
+ ****************************************************************************/
+
+void up_release_pending(void)
+{
+  struct tcb_s *rtcb = this_task();
+
+  sinfo("From TCB=%p\n", rtcb);
+
+  /* Merge the g_pendingtasks list into the ready-to-run task list */
+
+  /* sched_lock(); */
+
+  if (sched_mergepending())
+    {
+      /* The currently active task has changed!  We will need to switch
+       * contexts.
+       *
+       * Update scheduler parameters.
+       */
+
+      sched_suspend_scheduler(rtcb);
+
+      /* Are we operating in interrupt context? */
+
+      if (g_current_regs)
+        {
+          /* Yes, then we have to do things differently.
+           * Just copy the g_current_regs into the OLD rtcb.
+           */
+
+           up_savestate(rtcb->xcp.regs);
+
+          /* Restore the exception context of the rtcb at the (new) head
+           * of the ready-to-run task list.
+           */
+
+          rtcb = this_task();
+
+          /* Update scheduler parameters */
+
+          sched_resume_scheduler(rtcb);
+
+          /* Then switch contexts.  Any necessary address environment
+           * changes will be made when the interrupt returns.
+           */
+
+          up_restorestate(rtcb->xcp.regs);
+        }
+
+      /* No, then we will need to perform the user context switch */
+
+      else
+        {
+          /* Switch context to the context of the task at the head of the
+           * ready to run list.
+           */
+
+          struct tcb_s *nexttcb = this_task();
+
+#ifdef CONFIG_ARCH_ADDRENV
+          /* Make sure that the address environment for the previously
+           * running task is closed down gracefully (data caches dump,
+           * MMU flushed) and set up the address environment for the new
+           * thread at the head of the ready-to-run list.
+           */
+
+          (void)group_addrenv(nexttcb);
+#endif
+          /* Update scheduler parameters */
+
+          sched_resume_scheduler(nexttcb);
+
+          /* Then switch contexts */
+
+          up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+
+          /* up_switchcontext forces a context switch to the task at the
+           * head of the ready-to-run list.  It does not 'return' in the
+           * normal sense.  When it does return, it is because the blocked
+           * task is again ready to run and has execution priority.
+           */
+        }
+    }
+}
diff --git a/arch/risc-v/src/rv64gc/up_reprioritizertr.c b/arch/risc-v/src/rv64gc/up_reprioritizertr.c
new file mode 100644
index 0000000..3d582ec
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/up_reprioritizertr.c
@@ -0,0 +1,203 @@
+/****************************************************************************
+ *  arch/risc-v/src/rv64gc/up_reprioritizertr.c
+ *
+ *   Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sched.h>
+#include <syscall.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/sched.h>
+
+#include "sched/sched.h"
+#include "group/group.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_reprioritize_rtr
+ *
+ * Description:
+ *   Called when the priority of a running or
+ *   ready-to-run task changes and the reprioritization will
+ *   cause a context switch.  Two cases:
+ *
+ *   1) The priority of the currently running task drops and the next
+ *      task in the ready to run list has priority.
+ *   2) An idle, ready to run task's priority has been raised above the
+ *      the priority of the current, running task and it now has the
+ *      priority.
+ *
+ * Input Parameters:
+ *   tcb: The TCB of the task that has been reprioritized
+ *   priority: The new task priority
+ *
+ ****************************************************************************/
+
+void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
+{
+  /* Verify that the caller is sane */
+
+  if (tcb->task_state < FIRST_READY_TO_RUN_STATE ||
+      tcb->task_state > LAST_READY_TO_RUN_STATE
+#if SCHED_PRIORITY_MIN > 0
+      || priority < SCHED_PRIORITY_MIN
+#endif
+#if SCHED_PRIORITY_MAX < UINT8_MAX
+      || priority > SCHED_PRIORITY_MAX
+#endif
+    )
+    {
+       DEBUGPANIC();
+    }
+  else
+    {
+      struct tcb_s *rtcb = this_task();
+      bool switch_needed;
+
+      sinfo("TCB=%p PRI=%d\n", tcb, priority);
+
+      /* Remove the tcb task from the ready-to-run list.
+       * sched_removereadytorun will return true if we just
+       * remove the head of the ready to run list.
+       */
+
+      switch_needed = sched_removereadytorun(tcb);
+
+      /* Setup up the new task priority */
+
+      tcb->sched_priority = (uint8_t)priority;
+
+      /* Return the task to the specified blocked task list.
+       * sched_addreadytorun will return true if the task was
+       * added to the new list.  We will need to perform a context
+       * switch only if the EXCLUSIVE or of the two calls is non-zero
+       * (i.e., one and only one the calls changes the head of the
+       * ready-to-run list).
+       */
+
+      switch_needed ^= sched_addreadytorun(tcb);
+
+      /* Now, perform the context switch if one is needed */
+
+      if (switch_needed)
+        {
+          /* If we are going to do a context switch, then now is the right
+           * time to add any pending tasks back into the ready-to-run list.
+           * task list now
+           */
+
+          if (g_pendingtasks.head)
+            {
+              sched_mergepending();
+            }
+
+          /* Update scheduler parameters */
+
+          sched_suspend_scheduler(rtcb);
+
+          /* Are we in an interrupt handler? */
+
+          if (g_current_regs)
+            {
+              /* Yes, then we have to do things differently.
+               * Just copy the g_current_regs into the OLD rtcb.
+               */
+
+               up_savestate(rtcb->xcp.regs);
+
+              /* Restore the exception context of the rtcb at the (new) head
+               * of the ready-to-run task list.
+               */
+
+              rtcb = this_task();
+
+              /* Update scheduler parameters */
+
+              sched_resume_scheduler(rtcb);
+
+              /* Then switch contexts.  Any necessary address environment
+               * changes will be made when the interrupt returns.
+               */
+
+              up_restorestate(rtcb->xcp.regs);
+            }
+
+          /* No, then we will need to perform the user context switch */
+
+          else
+            {
+              /* Switch context to the context of the task at the head of the
+               * ready to run list.
+               */
+
+              struct tcb_s *nexttcb = this_task();
+
+#ifdef CONFIG_ARCH_ADDRENV
+              /* Make sure that the address environment for the previously
+               * running task is closed down gracefully (data caches dump,
+               * MMU flushed) and set up the address environment for the new
+               * thread at the head of the ready-to-run list.
+               */
+
+              (void)group_addrenv(nexttcb);
+#endif
+              /* Update scheduler parameters */
+
+              sched_resume_scheduler(nexttcb);
+
+              /* Then switch contexts */
+
+              up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+
+              /* up_switchcontext forces a context switch to the task at the
+               * head of the ready-to-run list.  It does not 'return' in the
+               * normal sense.  When it does return, it is because the blocked
+               * task is again ready to run and has execution priority.
+               */
+            }
+        }
+    }
+}
diff --git a/arch/risc-v/src/rv64gc/up_sigdeliver.c b/arch/risc-v/src/rv64gc/up_sigdeliver.c
new file mode 100644
index 0000000..187eb3f
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/up_sigdeliver.c
@@ -0,0 +1,146 @@
+/****************************************************************************
+ * arch/risc-v/src/rv64gc/up_sigdeliver.c
+ *
+ *   Copyright (C) 2011, 2015, 2018-2018 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ *   Modified for RISC-V:
+ *
+ *   Copyright (C) 2016 Ken Pettit. All rights reserved.
+ *   Author: Ken Pettit <pe...@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <sched.h>
+#include <syscall.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+#include <arch/board/board.h>
+
+#include "sched/sched.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_sigdeliver
+ *
+ * Description:
+ *   This is the a signal handling trampoline.  When a signal action was
+ *   posted.  The task context was mucked with and forced to branch to this
+ *   location with interrupts disabled.
+ *
+ ****************************************************************************/
+
+void up_sigdeliver(void)
+{
+  struct tcb_s *rtcb = this_task();
+  uint64_t regs[XCPTCONTEXT_REGS];
+
+  /* Save the errno.  This must be preserved throughout the signal handling
+   * so that the user code final gets the correct errno value (probably
+   * EINTR).
+   */
+
+  int saved_errno = rtcb->pterrno;
+
+  board_autoled_on(LED_SIGNAL);
+
+  sinfo("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
+        rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
+  DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
+
+  /* Save the return state on the stack. */
+
+  up_copystate(regs, rtcb->xcp.regs);
+
+#ifndef CONFIG_SUPPRESS_INTERRUPTS
+  /* Then make sure that interrupts are enabled.  Signal handlers must always
+   * run with interrupts enabled.
+   */
+
+  up_irq_enable();
+#endif
+
+  /* Deliver the signals */
+
+  ((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb);
+
+  /* Output any debug messages BEFORE restoring errno (because they may
+   * alter errno), then disable interrupts again and restore the original
+   * errno that is needed by the user logic (it is probably EINTR).
+   */
+
+  sinfo("Resuming EPC: %08x INT_CTX: %08x\n",
+        regs[REG_EPC], regs[REG_INT_CTX]);
+
+  (void)up_irq_save();
+  rtcb->pterrno        = saved_errno;
+
+  /* Modify the saved return state with the actual saved values in the
+   * TCB.  This depends on the fact that nested signal handling is
+   * not supported.  Therefore, these values will persist throughout the
+   * signal handling action.
+   *
+   * Keeping this data in the TCB resolves a security problem in protected
+   * and kernel mode:  The regs[] array is visible on the user stack and
+   * could be modified by a hostile program.
+   */
+
+  regs[REG_EPC]        = rtcb->xcp.saved_epc;
+  regs[REG_INT_CTX]    = rtcb->xcp.saved_int_ctx;
+  rtcb->xcp.sigdeliver = NULL;  /* Allows next handler to be scheduled */
+
+  /* Then restore the correct state for this thread of
+   * execution.
+   */
+
+  board_autoled_off(LED_SIGNAL);
+  up_fullcontextrestore(regs);
+
+  /* up_fullcontextrestore() should not return but could if the software
+   * interrupts are disabled.
+   */
+
+  DEBUGPANIC();
+}
diff --git a/arch/risc-v/src/rv64gc/up_swint.c b/arch/risc-v/src/rv64gc/up_swint.c
new file mode 100644
index 0000000..0dfc921
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/up_swint.c
@@ -0,0 +1,286 @@
+/****************************************************************************
+ * arch/riscv/src/rv64gc/up_swint.c
+ *
+ *   Copyright (C) 2011-2012, 2015, 2019 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <syscall.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/sched.h>
+
+#include <arch/irq.h>
+
+#include "signal/signal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_registerdump
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_SYSCALL_INFO
+static void up_registerdump(const uint64_t *regs)
+{
+  svcinfo("EPC:%08x\n",
+          regs[REG_EPC]);
+  svcinfo("A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x A6:%08x A7:%08x\n",
+          regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3],
+          regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]);
+  svcinfo("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x\n",
+          regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3],
+          regs[REG_T4], regs[REG_T5], regs[REG_T6]);
+  svcinfo("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n",
+          regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3],
+          regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]);
+  svcinfo("S8:%08x S9:%08x S10:%08x S11:%08x\n",
+          regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]);
+#ifdef RISCV_SAVE_GP
+  svcinfo("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n",
+          regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP],
+          regs[REG_RA]);
+#else
+  svcinfo("SP:%08x FP:%08x TP:%08x RA:%08x\n",
+          regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]);
+#endif
+}
+#else
+#  define up_registerdump(regs)
+#endif
+
+/****************************************************************************
+ * Name: dispatch_syscall
+ *
+ * Description:
+ *   Call the stub function corresponding to the system call.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_BUILD_KERNEL
+static void dispatch_syscall(void) naked_function;
+static void dispatch_syscall(void)
+{
+#  error "Missing logic"
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_swint
+ *
+ * Description:
+ *   This is software interrupt exception handler that performs context
+ *   switching and manages system calls
+ *
+ ****************************************************************************/
+
+int up_swint(int irq, FAR void *context, FAR void *arg)
+{
+  uint64_t *regs = (uint64_t *)context;
+
+  DEBUGASSERT(regs && regs == g_current_regs);
+
+  /* Software interrupt 0 is invoked with REG_A0 (REG_X10) = system call
+   * command and REG_A1-6 = variable number of
+   * arguments depending on the system call.
+   */
+
+#ifdef CONFIG_DEBUG_SYSCALL_INFO
+  svcinfo("Entry: regs: %p cmd: %d\n", regs, regs[REG_A0]);
+  up_registerdump(regs);
+#endif
+
+  /* Handle the SWInt according to the command in $a0 */
+
+  switch (regs[REG_A0])
+    {
+      /* A0=SYS_restore_context: This a restore context command:
+       *
+       *   void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
+       *
+       * At this point, the following values are saved in context:
+       *
+       *   A0 = SYS_restore_context
+       *   A1 = restoreregs
+       *
+       * In this case, we simply need to set g_current_regs to restore register
+       * area referenced in the saved R1. context == g_current_regs is the normal
+       * exception return.  By setting g_current_regs = context[R1], we force
+       * the return to the saved context referenced in $a1.
+       */
+
+      case SYS_restore_context:
+        {
+          DEBUGASSERT(regs[REG_A1] != 0);
+          g_current_regs = (uint64_t *)regs[REG_A1];
+        }
+        break;
+
+      /* A0=SYS_switch_context: This a switch context command:
+       *
+       *   void up_switchcontext(uint64_t *saveregs, uint64_t *restoreregs);
+       *
+       * At this point, the following values are saved in context:
+       *
+       *   A0 = SYS_switch_context
+       *   A1 = saveregs
+       *   A2 = restoreregs
+       *
+       * In this case, we save the context registers to the save register
+       * area referenced by the saved contents of R5 and then set
+       * g_current_regs to the save register area referenced by the saved
+       * contents of R6.
+       */
+
+      case SYS_switch_context:
+        {
+          DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
+          up_copystate((uint64_t *)regs[REG_A1], regs);
+          g_current_regs = (uint64_t *)regs[REG_A2];
+        }
+        break;
+
+      /* A0=SYS_syscall_return: This a switch context command:
+       *
+       *   void up_sycall_return(void);
+       *
+       * At this point, the following values are saved in context:
+       *
+       *   A0 = SYS_syscall_return
+       *
+       * We need to restore the saved return address and return in
+       * unprivileged thread mode.
+       */
+
+#ifdef CONFIG_BUILD_KERNEL
+      case SYS_syscall_return:
+        {
+          struct tcb_s *rtcb = sched_self();
+          int index = (int)rtcb->xcp.nsyscalls - 1;
+
+          /* Make sure that there is a saved syscall return address. */
+
+          DEBUGASSERT(index >= 0);
+
+          /* Setup to return to the saved syscall return address in
+           * the original mode.
+           */
+
+          g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn;
+#error "Missing logic -- need to restore the original mode"
+          rtcb->xcp.nsyscalls     = index;
+
+          /* Handle any signal actions that were deferred while processing
+           * the system call.
+           */
+
+          rtcb->flags            &= ~TCB_FLAG_SYSCALL;
+          (void)nxsig_unmask_pendingsignal();
+        }
+        break;
+#endif
+
+      /* This is not an architecture-specify system call.  If NuttX is built
+       * as a standalone kernel with a system call interface, then all of the
+       * additional system calls must be handled as in the default case.
+       */
+
+      default:
+        {
+#ifdef CONFIG_BUILD_KERNEL
+          FAR struct tcb_s *rtcb = sched_self();
+          int index = rtcb->xcp.nsyscalls;
+
+          /* Verify that the SYS call number is within range */
+
+          DEBUGASSERT(g_current_regs[REG_A0] < SYS_maxsyscall);
+
+          /* Make sure that we got here that there is a no saved syscall
+           * return address.  We cannot yet handle nested system calls.
+           */
+
+          DEBUGASSERT(index < CONFIG_SYS_NNEST);
+
+          /* Setup to return to dispatch_syscall in privileged mode. */
+
+          rtcb->xcpsyscall[index].sysreturn = regs[REG_EPC];
+#error "Missing logic -- Need to save mode"
+          rtcb->xcp.nsyscalls  = index + 1;
+
+          regs[REG_EPC]        = (uint32_t)dispatch_syscall;
+#error "Missing logic -- Need to set privileged mode"
+
+          /* Offset R0 to account for the reserved values */
+
+          g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED;
+
+          /* Indicate that we are in a syscall handler. */
+
+          rtcb->flags            |= TCB_FLAG_SYSCALL;
+#else
+          svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]);
+#endif
+        }
+        break;
+    }
+
+  /* Report what happened.  That might difficult in the case of a context switch */
+
+#ifdef CONFIG_DEBUG_SYSCALL_INFO
+  if (regs != g_current_regs)
+    {
+      svcinfo("SWInt Return: Context switch!\n");
+      up_registerdump((const uint32_t *)g_current_regs);
+    }
+  else
+    {
+      svcinfo("SWInt Return: %d\n", regs[REG_A0]);
+    }
+#endif
+
+  return OK;
+}
diff --git a/arch/risc-v/include/syscall.h b/arch/risc-v/src/rv64gc/up_syscall.S
similarity index 59%
copy from arch/risc-v/include/syscall.h
copy to arch/risc-v/src/rv64gc/up_syscall.S
index 1616cb4..84e498a 100644
--- a/arch/risc-v/include/syscall.h
+++ b/arch/risc-v/src/rv64gc/up_syscall.S
@@ -1,10 +1,13 @@
 /****************************************************************************
- * arch/risc-v/include/syscall.h
+ * arch/riscv/src/rv64gc/up_syscall.S
  *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
  *
- *   Modified 2016 by Ken Pettit for RISC-V architecture.
+ *   Modified for RISC-V:
+ *
+ *   Copyright (C) 2016 Ken Pettit. All rights reserved.
+ *   Author: Ken Pettit <pe...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,57 +38,75 @@
  *
  ****************************************************************************/
 
-/* This file should never be included directed but, rather, only indirectly
- * through include/syscall.h or include/sys/sycall.h
- */
-
-#ifndef __ARCH_RISCV_INCLUDE_SYSCALL_H
-#define __ARCH_RISCV_INCLUDE_SYSCALL_H
-
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
-/* Include RISC-V architecture-specific syscall macros */
-
-#ifdef CONFIG_ARCH_RV32IM
-# include <arch/rv32im/syscall.h>
-#endif
+#include <nuttx/config.h>
 
 /****************************************************************************
- * Pre-processor Definitions
+ * Public Symbols
  ****************************************************************************/
 
+	.file	"up_syscall0.S"
+	.global sys_call0
+	.global sys_call1
+	.global sys_call2
+	.global sys_call3
+	.global sys_call4
+	.global sys_call5
+
 /****************************************************************************
- * Public Types
+ * Private Data
  ****************************************************************************/
 
 /****************************************************************************
- * Inline functions
+ * Private Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Public Data
+ * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Public Function Prototypes
+ * Name: up_syscall0, up_syscall1, up_syscall2, up_syscall3
+ *
+ * Description:
+ *   up_syscall0 - System call SYS_ argument and no additional parameters.
+ *   up_syscall1 - System call SYS_ argument and one additional parameter.
+ *   up_syscall2 - System call SYS_ argument and two additional parameters.
+ *   up_syscall3 - System call SYS_ argument and three additional parameters.
+ *   up_syscall4 - System call SYS_ argument and four additional parameters.
+ *   up_syscall5 - System call SYS_ argument and five additional parameters.
+ *
+ * Assumption:
+ *   All interrupts are disabled except for the software interrupts.
+ *
  ****************************************************************************/
 
-#ifndef __ASSEMBLY__
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C"
-{
-#else
-#define EXTERN extern
-#endif
-
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
-#endif
-
-#endif /* __ARCH_RISCV_INCLUDE_SYSCALL_H */
+	.text
+
+sys_call0:	/* a0 holds the syscall number */
+sys_call1:	/* a0 holds the syscall number, argument in a1 */
+sys_call2:	/* a0 holds the syscall number, arguments in a1 and a2 */
+sys_call3:	/* a0 holds the syscall number, arguments in a1, a2, and a3 */
+sys_call4:	/* a0 holds the syscall number, arguments in a1, a2, a3 and a4 */
+sys_call5:	/* a0 holds the syscall number, arguments in a1, a2, a3, a4 and a5 */
+
+	/* Issue the ECALL opcode to perform a SW interrupt to the OS */
+
+   ecall
+
+	/* The actual interrupt may not a occur for a few more cycles.  Let's
+	 * put a few nop's here in hope that the SW interrupt occurs during
+	 * the sequence of nops.
+	 */
+
+	nop
+	nop
+
+	/* Then return with the result of the software interrupt in v0 */
+
+	ret
+	nop
 
diff --git a/arch/risc-v/src/rv64gc/up_unblocktask.c b/arch/risc-v/src/rv64gc/up_unblocktask.c
new file mode 100644
index 0000000..70b0e59
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/up_unblocktask.c
@@ -0,0 +1,163 @@
+/****************************************************************************
+ *  arch/risc-v/src/rv64gc/up_unblocktask.c
+ *
+ *   Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <syscall.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/sched.h>
+
+#include "sched/sched.h"
+#include "group/group.h"
+#include "clock/clock.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_unblock_task
+ *
+ * Description:
+ *   A task is currently in an inactive task list
+ *   but has been prepped to execute.  Move the TCB to the
+ *   ready-to-run list, restore its context, and start execution.
+ *
+ * Input Parameters:
+ *   tcb: Refers to the tcb to be unblocked.  This tcb is
+ *     in one of the waiting tasks lists.  It must be moved to
+ *     the ready-to-run list and, if it is the highest priority
+ *     ready to run task, executed.
+ *
+ ****************************************************************************/
+
+void up_unblock_task(struct tcb_s *tcb)
+{
+  struct tcb_s *rtcb = this_task();
+
+  /* Verify that the context switch can be performed */
+
+  DEBUGASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) &&
+              (tcb->task_state <= LAST_BLOCKED_STATE));
+
+  /* Remove the task from the blocked task list */
+
+  sched_removeblocked(tcb);
+
+  /* Add the task in the correct location in the prioritized
+   * ready-to-run task list
+   */
+
+  if (sched_addreadytorun(tcb))
+    {
+      /* The currently active task has changed! We need to do
+       * a context switch to the new task.
+       */
+
+      /* Update scheduler parameters */
+
+      sched_suspend_scheduler(rtcb);
+
+      /* Are we in an interrupt handler? */
+
+      if (g_current_regs)
+        {
+          /* Yes, then we have to do things differently.
+           * Just copy the g_current_regs into the OLD rtcb.
+           */
+
+          up_savestate(rtcb->xcp.regs);
+
+          /* Restore the exception context of the rtcb at the (new) head
+           * of the ready-to-run task list.
+           */
+
+          rtcb = this_task();
+
+          /* Update scheduler parameters */
+
+          sched_resume_scheduler(rtcb);
+
+          /* Then switch contexts.  Any necessary address environment
+           * changes will be made when the interrupt returns.
+           */
+
+          up_restorestate(rtcb->xcp.regs);
+        }
+
+      /* No, then we will need to perform the user context switch */
+
+      else
+        {
+          /* Restore the exception context of the new task that is ready to
+           * run (probably tcb).  This is the new rtcb at the head of the
+           * ready-to-run task list.
+           */
+
+          struct tcb_s *nexttcb = this_task();
+
+#ifdef CONFIG_ARCH_ADDRENV
+          /* Make sure that the address environment for the previously
+           * running task is closed down gracefully (data caches dump,
+           * MMU flushed) and set up the address environment for the new
+           * thread at the head of the ready-to-run list.
+           */
+
+          (void)group_addrenv(nexttcb);
+#endif
+          /* Update scheduler parameters */
+
+          sched_resume_scheduler(nexttcb);
+
+          /* Then switch contexts */
+
+          up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+
+          /* up_switchcontext forces a context switch to the task at the
+           * head of the ready-to-run list.  It does not 'return' in the
+           * normal sense.  When it does return, it is because the blocked
+           * task is again ready to run and has execution priority.
+           */
+        }
+    }
+}
diff --git a/boards/Kconfig b/boards/Kconfig
index f915ee3..cb1b79b 100644
--- a/boards/Kconfig
+++ b/boards/Kconfig
@@ -539,6 +539,13 @@ config ARCH_BOARD_LX_CPU
 		for further information.  This board features the NXP LPC4088
 		(compatible with LPC1788) and Xilinx Spartan 6 XC6SLX9
 
+config ARCH_BOARD_MAIX_BIT
+	bool "Sipeed Maix Bit board"
+	depends on ARCH_CHIP_K210
+	---help---
+		This is the board configuration for the port of NuttX to the
+		Sipeed Maix Bit board. This board features the RISC-V K210
+
 config ARCH_BOARD_MAX32660_EVSYS
 	bool "Maxim Integrated MAX32660-EVSYS"
 	depends on ARCH_CHIP_MAX32660
@@ -2045,6 +2052,7 @@ config ARCH_BOARD
 	default "lpcxpresso-lpc1768"       if ARCH_BOARD_LPCXPRESSO
 	default "lpcxpresso-lpc54628"      if ARCH_BOARD_LPCXPRESSO_LPC54628
 	default "lx_cpu"                   if ARCH_BOARD_LX_CPU
+	default "maix-bit"                 if ARCH_BOARD_MAIX_BIT
 	default "maple"                    if ARCH_BOARD_MAPLE
 	default "makerlisp"                if ARCH_BOARD_MAKERLISP
 	default "max32660-evsys"           if ARCH_BOARD_MAX32660_EVSYS
@@ -2746,6 +2754,9 @@ endif
 if ARCH_BOARD_HIFIVE_REVB
 source "boards/risc-v/fe310/hifive1-revb/Kconfig"
 endif
+if ARCH_BOARD_MAIX_BIT
+source "boards/risc-v/k210/maix-bit/Kconfig"
+endif
 if ARCH_BOARD_SIM
 source "boards/sim/sim/sim/Kconfig"
 endif
diff --git a/boards/risc-v/k210/drivers/Kconfig b/boards/risc-v/k210/drivers/Kconfig
new file mode 100644
index 0000000..f72f3c0
--- /dev/null
+++ b/boards/risc-v/k210/drivers/Kconfig
@@ -0,0 +1,4 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
diff --git a/boards/risc-v/k210/maix-bit/Kconfig b/boards/risc-v/k210/maix-bit/Kconfig
new file mode 100644
index 0000000..bff5ee8
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/Kconfig
@@ -0,0 +1,8 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+if ARCH_BOARD_MAIX_BIT
+
+endif
diff --git a/boards/risc-v/k210/maix-bit/README.txt b/boards/risc-v/k210/maix-bit/README.txt
new file mode 100644
index 0000000..b240d83
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/README.txt
@@ -0,0 +1,35 @@
+1. Download and install toolchain and openocd-k210
+
+  $ curl https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14.tar.gz
+
+2. Build openocd-k210
+
+  $ git clone https://github.com/kendryte/openocd-kendryte
+  $ cd openocd-kendryte
+  $ ./bootstrap & ./configure & make
+
+3. Configure and build NuttX
+
+  $ mkdir ./nuttx; cd ./nuttx
+  $ git clone https://bitbucket.org/nuttx/nuttx.git
+  $ git clone https://bitbucket.org/nuttx/apps.git
+  $ cd nuttx
+  $ make distclean
+  $ ./tools/configure.sh maix-bit:nsh
+  $ make V=1
+
+4. Download and run the nuttx from SRAM (not SPI-Flash)
+
+  $ picocom -b 115200 /dev/ttyUSB0
+  $ sudo ./src/openocd -s ./tcl -f ./tcl/kendryte.cfg -m 0
+  $ riscv64-unknown-elf-gdb ./nuttx
+  (gdb) target extended-remote :3333
+  (gdb) load nuttx
+  (gdb) c
+
+5. TODO
+
+  PLL setting (currently CPU clock freq is assumed to be 416MHz)
+  Boot from SPI-Flash
+  Support peripherals such as GPIO/SPI/I2C/...
+  Support RISC-V User mode
diff --git a/boards/risc-v/k210/maix-bit/configs/nsh/defconfig b/boards/risc-v/k210/maix-bit/configs/nsh/defconfig
new file mode 100644
index 0000000..e8ceae4
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/configs/nsh/defconfig
@@ -0,0 +1,65 @@
+#
+# 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_NSH_DISABLE_LOSMART is not set
+# CONFIG_STANDARD_SERIAL is not set
+CONFIG_ARCH="risc-v"
+CONFIG_ARCH_BOARD="maix-bit"
+CONFIG_ARCH_BOARD_MAIX_BIT=y
+CONFIG_ARCH_CHIP="k210"
+CONFIG_ARCH_CHIP_K210=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_RISCV=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BINFMT_DISABLE=y
+CONFIG_BOARD_LOOPSPERMSEC=15000
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEV_ZERO=y
+CONFIG_EXAMPLES_HELLO=y
+CONFIG_FS_PROCFS=y
+CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_INTELHEX_BINARY=y
+CONFIG_LIBC_PERROR_STDOUT=y
+CONFIG_LIBC_STRERROR=y
+CONFIG_MAX_TASKS=64
+CONFIG_MAX_WDOGPARMS=2
+CONFIG_NFILE_STREAMS=8
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+CONFIG_NSH_DISABLE_MKDIR=y
+CONFIG_NSH_DISABLE_RM=y
+CONFIG_NSH_DISABLE_RMDIR=y
+CONFIG_NSH_DISABLE_UMOUNT=y
+CONFIG_NSH_FILEIOSIZE=64
+CONFIG_NSH_READLINE=y
+CONFIG_NSH_STRERROR=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_PREALLOC_WDOGS=16
+CONFIG_RAM_SIZE=2097152
+CONFIG_RAM_START=0x80400000
+CONFIG_RAW_BINARY=y
+CONFIG_READLINE_CMD_HISTORY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_STACK_COLORATION=y
+CONFIG_START_DAY=28
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2019
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=20
+CONFIG_TESTING_GETPRIME=y
+CONFIG_TESTING_GETPRIME_STACKSIZE=2048
+CONFIG_TESTING_OSTEST=y
+CONFIG_UART0_RXBUFSIZE=8
+CONFIG_UART0_SERIAL_CONSOLE=y
+CONFIG_UART0_TXBUFSIZE=8
+CONFIG_USERMAIN_STACKSIZE=3072
+CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_WDOG_INTRESERVE=0
diff --git a/arch/risc-v/src/common/up_arch.h b/boards/risc-v/k210/maix-bit/include/board.h
similarity index 76%
copy from arch/risc-v/src/common/up_arch.h
copy to boards/risc-v/k210/maix-bit/include/board.h
index ee7ed9c..05da1fc 100644
--- a/arch/risc-v/src/common/up_arch.h
+++ b/boards/risc-v/k210/maix-bit/include/board.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_arch.h
+ * boards/risc-v/k210/maix-bit/include/board.h
  *
- *   Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,37 +33,29 @@
  *
  ****************************************************************************/
 
-#ifndef ___ARCH_RISCV_SRC_COMMON_UP_ARCH_H
-#define ___ARCH_RISCV_SRC_COMMON_UP_ARCH_H
+#ifndef __BOARDS_RISCV_K210_MAIX_BIT_INCLUDE_BOARD_H
+#define __BOARDS_RISCV_K210_MAIX_BIT_INCLUDE_BOARD_H
 
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
 #include <nuttx/config.h>
+
 #ifndef __ASSEMBLY__
 # include <stdint.h>
 #endif
 
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
+#include "k210.h"
 
 /****************************************************************************
- * Inline Functions
+ * Public Types
  ****************************************************************************/
 
 #ifndef __ASSEMBLY__
 
-# define getreg8(a)           (*(volatile uint8_t *)(a))
-# define putreg8(v,a)         (*(volatile uint8_t *)(a) = (v))
-# define getreg16(a)          (*(volatile uint16_t *)(a))
-# define putreg16(v,a)        (*(volatile uint16_t *)(a) = (v))
-# define getreg32(a)          (*(volatile uint32_t *)(a))
-# define putreg32(v,a)        (*(volatile uint32_t *)(a) = (v))
-
 /****************************************************************************
- * Public Function Prototypes
+ * Public Data
  ****************************************************************************/
 
 #undef EXTERN
@@ -75,14 +67,20 @@ extern "C"
 #define EXTERN extern
 #endif
 
-/* Atomic modification of registers */
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: k210_boardinitialize
+ ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits);
+void k210_boardinitialize(void);
 
 #undef EXTERN
 #if defined(__cplusplus)
 }
 #endif
-
 #endif /* __ASSEMBLY__ */
-#endif  /* ___ARCH_ARM_SRC_COMMON_UP_ARCH_H */
+#endif /* __BOARDS_RISC-V_K210_MAIX_BIT_INCLUDE_BOARD_H */
+
diff --git a/boards/risc-v/k210/maix-bit/scripts/Make.defs b/boards/risc-v/k210/maix-bit/scripts/Make.defs
new file mode 100644
index 0000000..de0e6e5
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/scripts/Make.defs
@@ -0,0 +1,112 @@
+############################################################################
+# boards/risc-v/fe310/maix-bit/scripts/Make.defs
+#
+#   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+#   Author: Masayuki Ishikawa <ma...@gmail.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+include ${TOPDIR}/.config
+include ${TOPDIR}/tools/Config.mk
+include ${TOPDIR}/arch/risc-v/src/rv64gc/Toolchain.defs
+
+LDSCRIPT = ld.script
+
+ifeq ($(WINTOOL),y)
+  # Windows-native toolchains
+  DIRLINK = $(TOPDIR)/tools/copydir.sh
+  DIRUNLINK = $(TOPDIR)/tools/unlink.sh
+  MKDEP = $(TOPDIR)/tools/mkwindeps.sh
+  ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}"
+  ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}"
+  ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/boards/$(CONFIG_ARCH)/$(CONFIG_ARCH_CHIP)/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
+else
+  # Linux/Cygwin-native toolchain
+  MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT)
+  ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
+  ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
+  ARCHSCRIPT = -T$(TOPDIR)/boards/$(CONFIG_ARCH)/$(CONFIG_ARCH_CHIP)/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
+endif
+
+CC = $(CROSSDEV)gcc
+CXX = $(CROSSDEV)g++
+CPP = $(CROSSDEV)gcc -E
+LD = $(CROSSDEV)ld
+STRIP = $(CROSSDEV)strip --strip-unneeded
+AR = $(ARCROSSDEV)ar rcs
+NM = $(ARCROSSDEV)nm
+OBJCOPY = $(CROSSDEV)objcopy
+OBJDUMP = $(CROSSDEV)objdump
+
+ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'}
+ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
+
+ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
+  ARCHOPTIMIZATION = -g
+  ASARCHCPUFLAGS += -Wa,-g
+endif
+
+MAXOPTIMIZATION = -Os
+
+ifneq ($(CONFIG_DEBUG_NOOPT),y)
+  ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer
+endif
+
+ARCHCPUFLAGS = -march=rv64gc -mabi=lp64 -mcmodel=medany
+ARCHCFLAGS = -fno-builtin -ffunction-sections -fdata-sections
+ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti
+ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
+ARCHWARNINGSXX = -Wall -Wshadow -Wundef
+ARCHDEFINES =
+ARCHPICFLAGS =
+
+CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
+CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
+CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
+CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
+CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
+AFLAGS += $(CFLAGS) -D__ASSEMBLY__ $(ASARCHCPUFLAGS)
+
+NXFLATLDFLAGS1 = -r -d -warn-common
+NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
+LDNXFLATFLAGS = -e main -s 2048
+
+ASMEXT = .S
+OBJEXT = .o
+LIBEXT = .a
+EXEEXT =
+
+LDFLAGS += --gc-sections -melf64lriscv
+
+HOSTCC = gcc
+HOSTINCLUDES = -I.
+HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe
+HOSTLDFLAGS =
+
diff --git a/boards/risc-v/k210/maix-bit/scripts/ld.script b/boards/risc-v/k210/maix-bit/scripts/ld.script
new file mode 100644
index 0000000..4809de0
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/scripts/ld.script
@@ -0,0 +1,125 @@
+/****************************************************************************
+ * boards/risc-v/k210/maix-bit/scripts/ld.script
+ *
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/* Reg   Access        Start addr    End addr     Size
+ * MEM0  CPU w/  cache  0x80000000 - 0x803fffff : 4MB
+ * MEM1  CPU w/  cache  0x80400000 - 0x805fffff : 2MB
+ * MEM0  CPU w/o cache  0x40000000 - 0x403fffff : 4MB
+ * MEM1  CPU w/o cache  0x40400000 - 0x405fffff : 4MB
+ */
+
+MEMORY
+{
+  progmem (rx) : ORIGIN = 0x80000000, LENGTH = 4096K  /* w/ cache */
+  sram   (rwx) : ORIGIN = 0x80400000, LENGTH = 2048K  /* w/ cache */
+}
+
+OUTPUT_ARCH("riscv")
+
+ENTRY(_stext)
+EXTERN(_vectors)
+SECTIONS
+{
+    .text : {
+        _stext = ABSOLUTE(.);
+        *(.vectors)
+        *(.text .text.*)
+        *(.fixup)
+        *(.gnu.warning)
+        *(.rodata .rodata.* .srodata .srodata.*)
+        *(.gnu.linkonce.t.*)
+        *(.glue_7)
+        *(.glue_7t)
+        *(.got)
+        *(.gcc_except_table)
+        *(.gnu.linkonce.r.*)
+        _etext = ABSOLUTE(.);
+    } > progmem
+
+    .init_section : ALIGN(4) {
+        _sinit = ABSOLUTE(.);
+        KEEP(*(.init_array .init_array.*))
+        _einit = ABSOLUTE(.);
+    } > progmem
+
+    .ARM.extab : ALIGN(4) {
+        *(.ARM.extab*)
+    } > progmem
+
+    .ARM.exidx : ALIGN(4) {
+        __exidx_start = ABSOLUTE(.);
+        *(.ARM.exidx*)
+        __exidx_end = ABSOLUTE(.);
+    } > progmem
+
+    _eronly = ABSOLUTE(.);
+
+    .data : ALIGN(4) {
+        _sdata = ABSOLUTE(.);
+        *(.data .data.*)
+        *(.sdata .sdata.* .sdata2.*)
+        *(.gnu.linkonce.d.*)
+        *(.gnu.linkonce.s.*)
+        CONSTRUCTORS
+        . = ALIGN(4);
+        _edata = ABSOLUTE(.);
+    } > sram AT > progmem
+
+    .bss : ALIGN(4) {
+        _sbss = ABSOLUTE(.);
+        *(.bss .bss.*)
+        *(.sbss .sbss.*)
+        *(.gnu.linkonce.b.*)
+        *(.gnu.linkonce.sb.*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = ABSOLUTE(.);
+    } > sram
+
+    /* 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) }
+}
diff --git a/boards/risc-v/k210/maix-bit/src/Makefile b/boards/risc-v/k210/maix-bit/src/Makefile
new file mode 100644
index 0000000..8b9312f
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/src/Makefile
@@ -0,0 +1,44 @@
+############################################################################
+# boards/risc-v/k210/hifive1-revb/src/Makefile
+#
+#   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+#   Author: Masayuki Ishikawa <ma...@gmail.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+-include $(TOPDIR)/Make.defs
+
+CSRCS  = k210_bringup.c k210_boot.c
+
+ifeq ($(CONFIG_LIB_BOARDCTL),y)
+CSRCS += k210_appinit.c
+endif
+
+include $(TOPDIR)/boards/Board.mk
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/boards/risc-v/k210/maix-bit/src/k210_appinit.c
similarity index 60%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to boards/risc-v/k210/maix-bit/src/k210_appinit.c
index 6746e43..7672a63 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/boards/risc-v/k210/maix-bit/src/k210_appinit.c
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * boards/risc-v/k210/maix-bit/src/k210_appinit.c
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,35 +39,52 @@
 
 #include <nuttx/config.h>
 
-#include <stdint.h>
-#include <debug.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <errno.h>
 
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
+#include <nuttx/board.h>
 
-#include "up_arch.h"
+#include "k210.h"
+#include "maix-bit.h"
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: modifyreg32
+ * Name: board_app_initialize
  *
  * Description:
- *   Atomically modify the specified bits in a memory mapped register
+ *   Perform architecture specific initialization
+ *
+ * Input Parameters:
+ *   arg - The boardctl() argument is passed to the board_app_initialize()
+ *         implementation without modification.  The argument has no
+ *         meaning to NuttX; the meaning of the argument is a contract
+ *         between the board-specific initialization logic and the
+ *         matching application logic.  The value cold be such things as a
+ *         mode enumeration value, a set of DIP switch switch settings, a
+ *         pointer to configuration data read from a file or serial FLASH,
+ *         or whatever you would like to do with it.  Every implementation
+ *         should accept zero/NULL as a default configuration.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned on
+ *   any failure to indicate the nature of the failure.
  *
  ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
+int board_app_initialize(uintptr_t arg)
 {
-  irqstate_t flags;
-  uint32_t   regval;
+#ifdef CONFIG_BOARD_LATE_INITIALIZE
+  /* Board initialization already performed by board_late_initialize() */
+
+  return OK;
+#else
+  /* Perform board-specific initialization */
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
+  return k210_bringup();
+#endif
 }
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/boards/risc-v/k210/maix-bit/src/k210_boot.c
similarity index 72%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to boards/risc-v/k210/maix-bit/src/k210_boot.c
index 6746e43..9622361 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/boards/risc-v/k210/maix-bit/src/k210_boot.c
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * boards/risc-v/k210/maix-bit/src/k210_boot.c
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,35 +39,33 @@
 
 #include <nuttx/config.h>
 
-#include <stdint.h>
 #include <debug.h>
 
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
+#include <arch/board/board.h>
 
-#include "up_arch.h"
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: modifyreg32
+ * Name: k210_boardinitialize
  *
  * Description:
- *   Atomically modify the specified bits in a memory mapped register
+ *   All K210 architectures must provide the following entry point.
+ *   This entry point is called early in the intitialization -- after all
+ *   memory has been configured and mapped but before any devices have been
+ *   initialized.
  *
  ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
+void k210_boardinitialize(void)
 {
-  irqstate_t flags;
-  uint32_t   regval;
-
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
 }
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/boards/risc-v/k210/maix-bit/src/k210_bringup.c
similarity index 77%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to boards/risc-v/k210/maix-bit/src/k210_bringup.c
index 6746e43..e822a61 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/boards/risc-v/k210/maix-bit/src/k210_bringup.c
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * boards/risc-v/k210/maix-bit/src/k210_bringup.c
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,35 +39,37 @@
 
 #include <nuttx/config.h>
 
-#include <stdint.h>
-#include <debug.h>
+#include <sys/mount.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <errno.h>
 
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
+#include <nuttx/board.h>
 
-#include "up_arch.h"
+#include "k210.h"
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: modifyreg32
- *
- * Description:
- *   Atomically modify the specified bits in a memory mapped register
- *
+ * Name: k210_bringup
  ****************************************************************************/
 
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
+int k210_bringup(void)
 {
-  irqstate_t flags;
-  uint32_t   regval;
+  int ret = OK;
+
+#ifdef CONFIG_FS_PROCFS
+  /* Mount the procfs file system */
+
+  ret = mount(NULL, "/proc", "procfs", 0, NULL);
+  if (ret < 0)
+    {
+      serr("ERROR: Failed to mount procfs at %s: %d\n", "/proc", ret);
+    }
+#endif
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
+  return ret;
 }
diff --git a/arch/risc-v/src/common/up_modifyreg32.c b/boards/risc-v/k210/maix-bit/src/maix-bit.h
similarity index 65%
copy from arch/risc-v/src/common/up_modifyreg32.c
copy to boards/risc-v/k210/maix-bit/src/maix-bit.h
index 6746e43..a9fe917 100644
--- a/arch/risc-v/src/common/up_modifyreg32.c
+++ b/boards/risc-v/k210/maix-bit/src/maix-bit.h
@@ -1,8 +1,8 @@
 /****************************************************************************
- * arch/risc-v/src/common/up_modifyreg32.c
+ * boards/risc-v/k210/maix-bit/src/maix-bit.h
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ *   Copyright (C) 2019 Masayuki Ishikawa. All rights reserved.
+ *   Author: Masayuki Ishikawa <ma...@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,41 +33,15 @@
  *
  ****************************************************************************/
 
+#ifndef __BOARDS_RISCV_K210_MAIX_BIT_SRC_MAIX_BIT_H
+#define __BOARDS_RISCV_K210_MAIX_BIT_SRC_MAIX_BIT_H
+
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
 #include <nuttx/config.h>
 
-#include <stdint.h>
-#include <debug.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include "up_arch.h"
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: modifyreg32
- *
- * Description:
- *   Atomically modify the specified bits in a memory mapped register
- *
- ****************************************************************************/
-
-void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
-{
-  irqstate_t flags;
-  uint32_t   regval;
+int k210_bringup(void);
 
-  flags   = spin_lock_irqsave();
-  regval  = getreg32(addr);
-  regval &= ~clearbits;
-  regval |= setbits;
-  putreg32(regval, addr);
-  spin_unlock_irqrestore(flags);
-}
+#endif /* __BOARDS_RISCV_K210_MAIX_BIT_SRC_MAIX_BIT_H */
diff --git a/tools/configure.sh b/tools/configure.sh
index d18edd0..321e087 100755
--- a/tools/configure.sh
+++ b/tools/configure.sh
@@ -149,7 +149,7 @@ chips="a1x am335x c5471 cxd56xx dm320 efm32 imx6 imxrt kinetis kl lc823450
  lpc17xx_40xx lpc214x lpc2378 lpc31xx lpc43xx lpc54xx max326xx moxart nrf52
  nuc1xx rx65n s32k1xx sam34 sama5 samd2l2 samd5e5 samv7 stm32 stm32f0l0g0 stm32f7 stm32h7
  stm32l4 str71x tiva tms570 xmc4 at32uc3 at90usb atmega mcs92s12ne64 pic32mx
- pic32mz lm32 mor1kx m32262f8 sh7032 fe310 gap8 nr5m100 sim qemu esp32 z16f2811
+ pic32mz lm32 mor1kx m32262f8 sh7032 fe310 k210 gap8 nr5m100 sim qemu esp32 z16f2811
  ez80 z180 z8 z80"
 
 for arc in ${archs}; do
diff --git a/tools/refresh.sh b/tools/refresh.sh
index a27390c..9bff249 100755
--- a/tools/refresh.sh
+++ b/tools/refresh.sh
@@ -123,7 +123,7 @@ CHIPLIST="a1x am335x c5471 cxd56xx dm320 efm32 imx6 imxrt kinetis kl lc823450
   lpc17xx_40xx lpc214x lpc2378 lpc31xx lpc43xx lpc54xx max326xx moxart nrf52
   nuc1xx rx65n s32k1xx sam34 sama5 samd2l2 samd5e5 samv7 stm32 stm32f0l0g0 stm32f7 stm32h7
   stm32l4 str71x tiva tms570 xmc4 at32uc3 at90usb atmega mcs92s12ne64 pic32mx
-  pic32mz lm32 mor1kx m32262f8 sh7032 fe310 gap8 nr5m100 sim qemu esp32 z16f2811
+  pic32mz lm32 mor1kx m32262f8 sh7032 fe310 k210 gap8 nr5m100 sim qemu esp32 z16f2811
   ez80 z180 z8 z80"
 
 for ARCH in ${ARCHLIST}; do
diff --git a/tools/testbuild.sh b/tools/testbuild.sh
index 99f59a5..3ddfc56 100755
--- a/tools/testbuild.sh
+++ b/tools/testbuild.sh
@@ -303,7 +303,7 @@ for line in $testlist; do
         lpc17xx_40xx lpc214x lpc2378 lpc31xx lpc43xx lpc54xx max326xx moxart nrf52
         nuc1xx rx65n s32k1xx sam34 sama5 samd2l2 samd5e5 samv7 stm32 stm32f0l0g0 stm32f7 stm32h7
         stm32l4 str71x tiva tms570 xmc4 at32uc3 at90usb atmega mcs92s12ne64 pic32mx
-        pic32mz lm32 mor1kx m32262f8 sh7032 fe310 gap8 nr5m100 sim qemu esp32 z16f2811
+        pic32mz lm32 mor1kx m32262f8 sh7032 fe310 k210 gap8 nr5m100 sim qemu esp32 z16f2811
         ez80 z180 z8 z80"
 
       for arch in ${ARCHLIST}; do