OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [examples/] [zephyr/] [v1.6.0-riscv64-base.diff] - Rev 5

Compare with Previous | Blame | View Log

diff --git a/arch/Kconfig b/arch/Kconfig
index c574947..200f486 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -37,6 +37,10 @@ config NIOS2
 	bool "Nios II Gen 2 architecture"
 	select ATOMIC_OPERATIONS_C
 
+config RISCV64
+	bool "RISC-V 64-bits architecture"
+	select ATOMIC_OPERATIONS_C
+
 endchoice
 
 #
diff --git a/arch/riscv64/Kbuild b/arch/riscv64/Kbuild
new file mode 100644
index 0000000..1573726
--- /dev/null
+++ b/arch/riscv64/Kbuild
@@ -0,0 +1,6 @@
+subdir-ccflags-y +=-I$(srctree)/include/drivers
+subdir-ccflags-y +=-I$(srctree)/drivers
+subdir-asflags-y += $(subdir-ccflags-y)
+
+obj-y += soc/$(SOC_PATH)/
+obj-y += core/
diff --git a/arch/riscv64/Kconfig b/arch/riscv64/Kconfig
new file mode 100644
index 0000000..e551376
--- /dev/null
+++ b/arch/riscv64/Kconfig
@@ -0,0 +1,76 @@
+# ARC EM4 options
+
+#
+# Copyright (c) 2014 Wind River Systems, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+choice
+	prompt "RISC-V SoC Selection"
+	depends on RISCV64
+
+	source "arch/riscv64/soc/*/Kconfig.soc"
+endchoice
+
+
+menu "RISC-V Options"
+	depends on RISCV64
+
+config ARCH
+	default "riscv64"
+
+config ARCH_DEFCONFIG
+	string
+	default "arch/riscv64/defconfig"
+
+config	NUM_IRQS
+	int
+	prompt "Upper limit of interrupt numbers/IDs used"
+	range 1 256
+	help
+	  Interrupts available will be 1 to NUM_IRQS-1.
+	  Interrupt pin 0 is hardcoded as unused.
+
+config RISCV_SYSTIMER
+	bool "Include System Timer"
+	default y
+
+config UART_RISCV_GNSS
+	bool "Include UART"
+	default y
+
+config CONSOLE
+	bool "Include Console"
+	default y
+
+config SRAM_SIZE
+	int "SRAM Size in kB"
+	default 256
+	help
+	This option specifies the size of the SRAM in kB.  It is normally set
+	by the platform's defconfig file and the user should generally avoid
+	modifying it via the menu configuration.
+
+config SRAM_BASE_ADDRESS
+	hex "SRAM Base Address"
+	default 0x10000000
+	help
+	This option specifies the base address of the SRAM on the platform.  It
+	is normally set by the platform's defconfig file and the user should
+	generally avoid modifying it via the menu configuration.
+
+
+source "arch/riscv64/soc/*/Kconfig"
+
+endmenu
diff --git a/arch/riscv64/Makefile b/arch/riscv64/Makefile
new file mode 100644
index 0000000..107faa8
--- /dev/null
+++ b/arch/riscv64/Makefile
@@ -0,0 +1,12 @@
+cflags-y += $(call cc-option,-ffunction-sections,) $(call cc-option,-fdata-sections,)
+cflags-$(CONFIG_LTO) = $(call cc-option,-flto,)
+
+soc_ld_include := -I$(srctree)/arch/$(ARCH)/soc/$(SOC_PATH)
+arch_cflags += $(soc_ld_include)
+EXTRA_LINKER_CMD_OPT += $(soc_ld_include)
+
+include $(srctree)/arch/$(ARCH)/soc/$(SOC_PATH)/Makefile
+
+KBUILD_CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += -Wno-unused-function
+KBUILD_CXXFLAGS += $(cflags-y)
diff --git a/arch/riscv64/_howto_build_riscv b/arch/riscv64/_howto_build_riscv
new file mode 100644
index 0000000..f82fc8a
--- /dev/null
+++ b/arch/riscv64/_howto_build_riscv
@@ -0,0 +1,4 @@
+cd samples/shell
+export ZEPHYR_BASE=/home/teeshina/svn/20170117_zephyr16/zephyr
+make ARCH=riscv64 CROSS_COMPILE=/home/teeshina/riscv/gnu-toolchain-rv64ima/bin/riscv64-unknown-elf- BOARD=riscv_gnss 2>&1 | tee _err.log
+elf2raw64 outdir/riscv_gnss/zephyr.elf -h -f 262144 -l 8 -o fwimage.hex
diff --git a/arch/riscv64/core/Makefile b/arch/riscv64/core/Makefile
new file mode 100644
index 0000000..638187f
--- /dev/null
+++ b/arch/riscv64/core/Makefile
@@ -0,0 +1,6 @@
+ccflags-y += -I$(srctree)/kernel/nanokernel/include
+ccflags-y +=-I$(srctree)/arch/$(ARCH)/include
+ccflags-y += -I$(srctree)/kernel/microkernel/include
+
+obj-y += cpu_idle.o fatal.o gptimers.o \
+	irq_manage.o swap.o new_thread.o memaccess.o
diff --git a/arch/riscv64/core/cpu_idle.c b/arch/riscv64/core/cpu_idle.c
new file mode 100644
index 0000000..5f13ec9
--- /dev/null
+++ b/arch/riscv64/core/cpu_idle.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014 Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * @brief CPU power management
+ *
+ * CPU power management routines.
+ */
+
+#include <toolchain.h>
+#include <sections.h>
+#include <arch/cpu.h>
+
+/*
+ * @brief Put the CPU in low-power mode
+ *
+ * This function always exits with interrupts unlocked.
+ *
+ * void nanCpuIdle(void)
+ */
+
+void nano_cpu_idle(void) {
+    _arch_irq_unlock(0);
+}
+/*
+ * @brief Put the CPU in low-power mode, entered with IRQs locked
+ *
+ * This function exits with interrupts restored to <key>.
+ *
+ * void nano_cpu_atomic_idle(unsigned int key)
+ */
+void nano_cpu_atomic_idle(unsigned int key) {
+    _arch_irq_unlock(key);
+}
+
+void sys_arch_reboot(int type) {
+	ARG_UNUSED(type);
+	//DO_REBOOT();
+}
diff --git a/arch/riscv64/core/fatal.c b/arch/riscv64/core/fatal.c
new file mode 100644
index 0000000..967e09a
--- /dev/null
+++ b/arch/riscv64/core/fatal.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013-2014 Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * @brief Nanokernel fatal error handler
+ *
+ * This module provides the _NanoFatalErrorHandler() routine.
+ */
+
+#include <toolchain.h>
+#include <sections.h>
+
+#include <nanokernel.h>
+#include <misc/printk.h>
+
+const NANO_ESF _default_esf = {
+	0xdeaddead, /* placeholder */
+};
+
+
+/**
+ *
+ * @brief Nanokernel fatal error handler
+ *
+ * This routine is called when a fatal error condition is detected by either
+ * hardware or software.
+ *
+ * The caller is expected to always provide a usable ESF.  In the event that the
+ * fatal error does not have a hardware generated ESF, the caller should either
+ * create its own or use a pointer to the global default ESF <_default_esf>.
+ *
+ * @param reason the reason that the handler was called
+ * @param pEsf pointer to the exception stack frame
+ *
+ * @return This function does not return.
+ */
+FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
+					  const NANO_ESF *pEsf)
+{
+
+#ifdef CONFIG_PRINTK
+       printk("***** Unhandled interrupt vector %d occurred! \n", -1);
+#endif
+    while (1) {}
+}
\ No newline at end of file
diff --git a/arch/riscv64/core/gptimers.c b/arch/riscv64/core/gptimers.c
new file mode 100644
index 0000000..8e5c856
--- /dev/null
+++ b/arch/riscv64/core/gptimers.c
@@ -0,0 +1,7 @@
+#include <stdint.h>
+
+//
+uint32_t _do_read_cpu_timestamp32(void) {
+    return 500;//READ32();
+}
+
diff --git a/arch/riscv64/core/irq_manage.c b/arch/riscv64/core/irq_manage.c
new file mode 100644
index 0000000..fb889ac
--- /dev/null
+++ b/arch/riscv64/core/irq_manage.c
@@ -0,0 +1,113 @@
+#include <nanokernel.h>
+#include <kernel_structs.h>
+#include <misc/__assert.h>
+#include <board.h>
+#include <sw_isr_table.h>
+#include <irq.h>
+#include <memaccess.h>
+
+_IsrTableEntry_t isr_demux_table[CONFIG_NUM_IRQS];
+
+void run_isr_handler(int idx, void *arg) {
+    if (isr_demux_table[idx].isr == 0) {
+        return;
+    }
+    _kernel.nested++;
+    ((NANO_EOI_GET_FUNC)isr_demux_table[idx].isr)(isr_demux_table[idx].arg);
+    _kernel.nested--;
+}
+
+unsigned int _arch_irq_lock(void) {
+    unsigned int ret = READ32(&__IRQCTRL->irq_lock);
+    WRITE32(&__IRQCTRL->irq_lock, 1);
+    return ret;
+}
+
+void _arch_irq_unlock(unsigned int key) {
+    WRITE32(&__IRQCTRL->irq_lock, key);
+}
+
+unsigned int _arch_irq_lock_state() {
+    return READ32(&__IRQCTRL->irq_lock);
+}
+
+/**
+ *
+ * @brief Enable an interrupt line
+ *
+ * Clear possible pending interrupts on the line, and enable the interrupt
+ * line. After this call, the CPU will receive interrupts for the specified
+ * <irq>.
+ *
+ * @return N/A
+ */
+void _arch_irq_enable(unsigned int irq)
+{
+	/* before enabling interrupts, ensure that interrupt is cleared */
+    uint32_t bit = READ32(&__IRQCTRL->irq_mask);
+    bit &= ~(1u << irq);
+    WRITE32(&__IRQCTRL->irq_clear, 1u << irq);
+    WRITE32(&__IRQCTRL->irq_mask, bit);
+}
+
+/**
+ *
+ * @brief Disable an interrupt line
+ *
+ * Disable an interrupt line. After this call, the CPU will stop receiving
+ * interrupts for the specified <irq>.
+ *
+ * @return N/A
+ */
+void _arch_irq_disable(unsigned int irq)
+{
+    uint32_t bit = READ32(&__IRQCTRL->irq_mask);
+    bit |= (1u << irq);
+    WRITE32(&__IRQCTRL->irq_mask, bit);
+}
+
+/*
+ * @internal
+ *
+ * @brief Replace an interrupt handler by another
+ *
+ * An interrupt's ISR can be replaced at runtime.
+ *
+ * @return N/A
+ */
+
+void _irq_handler_set(
+	unsigned int irq,
+	void (*new)(void *arg),
+	void *arg
+)
+{
+	int key = irq_lock();
+
+	__ASSERT(irq < CONFIG_NUM_IRQS, "IRQ number too high");
+	isr_demux_table[irq].arg = arg;
+    isr_demux_table[irq].isr = new;
+
+	irq_unlock(key);
+}
+
+/*
+ * @brief Connect an ISR to an interrupt line
+ *
+ * @a isr is connected to interrupt line @a irq, a number greater than or equal
+ * 16. No prior ISR can have been connected on @a irq interrupt line since the
+ * system booted.
+ *
+ * This routine will hang if another ISR was connected for interrupt line @a irq
+ * and ASSERT_ON is enabled; if ASSERT_ON is disabled, it will fail silently.
+ *
+ * @return the interrupt line number
+ */
+int _arch_irq_connect_dynamic(unsigned int irq, unsigned int priority,
+			     void (*routine)(void *arg), void *parameter,
+			     uint32_t flags)
+{
+	ARG_UNUSED(flags);
+	_irq_handler_set(irq, routine, parameter);
+	return irq;
+}
diff --git a/arch/riscv64/core/memaccess.c b/arch/riscv64/core/memaccess.c
new file mode 100644
index 0000000..52a46bb
--- /dev/null
+++ b/arch/riscv64/core/memaccess.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016, GNSS Sensor Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+uint16_t READ16(volatile uint16_t *addr)
+{
+    return *addr;
+}
+
+uint32_t READ32(volatile uint32_t *addr)
+{
+    return *addr;
+}
+
+uint64_t READ64(volatile uint64_t *addr)
+{
+    return *addr;
+}
+
+void WRITE32(volatile uint32_t *addr, uint32_t val)
+{
+    *addr = val;
+}
+
+void WRITE64(volatile uint64_t *addr, uint64_t val)
+{
+    *addr = val;
+}
diff --git a/arch/riscv64/core/new_thread.c b/arch/riscv64/core/new_thread.c
new file mode 100644
index 0000000..a8492f7
--- /dev/null
+++ b/arch/riscv64/core/new_thread.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2010-2015 Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * @brief Nanokernel thread support primitives
+ *
+ * This module provides core nanokernel fiber related primitives for the IA-32
+ * processor architecture.
+ */
+
+
+#include <kernel.h>
+#include <nano_internal.h>
+#include <kernel_structs.h>
+#include <wait_q.h>
+#include <string.h>
+#include <misc/printk.h>
+#include "swap_macros.h"
+
+#ifdef _WIN32
+extern int LIBH_create_thread(char *pStackMem,
+                              unsigned stackSize,
+                              int priority,
+                              unsigned options);
+#endif
+
+#if defined(CONFIG_THREAD_MONITOR)
+/*
+ * Add a thread to the kernel's list of active threads.
+ */
+static ALWAYS_INLINE void thread_monitor_init(struct k_thread *thread)
+{
+	unsigned int key;
+
+	key = irq_lock();
+	thread->next_thread = _kernel.threads;
+	_kernel.threads = thread;
+	irq_unlock(key);
+}
+#else
+#define thread_monitor_init(thread) \
+	do {/* do nothing */     \
+	} while ((0))
+#endif /* CONFIG_THREAD_MONITOR */
+
+
+struct init_stack_frame {
+	/* top of the stack / most recently pushed */
+
+	/* Used by _thread_entry_wrapper. pulls these off the stack and
+	 * into argument registers before calling _thread_entry()
+	 */
+	_thread_entry_t entry_point;
+	void *arg1;
+	void *arg2;
+	void *arg3;
+
+	/* least recently pushed */
+};
+
+
+/**
+ *
+ * @brief Create a new kernel execution thread
+ *
+ * This function is utilized to create execution threads for both fiber
+ * threads and kernel tasks.
+ */
+extern void _new_thread(char *pStack, size_t stackSize,
+			void (*pEntry)(void *, void *, void *),
+			void *p1, void *p2, void *p3,
+			int prio, unsigned options)
+{
+
+
+	_ASSERT_VALID_PRIO(priority, thread_func);
+
+	struct k_thread *thread;
+	unsigned long *pInitialCtx;
+
+#ifdef CONFIG_INIT_STACKS
+	memset(pStack, 0xaa, stackSize);
+#endif
+
+	/* Initialize various struct k_thread members */
+	thread = (struct k_thread *)pStack;
+	pInitialCtx =
+		(unsigned long *)(pStack + stackSize);
+
+
+	_init_thread_base(&thread->base, prio, K_PRESTART, options);
+
+	/* static threads overwrite it afterwards with real value */
+	thread->init_data = NULL;
+	thread->fn_abort = NULL;
+
+#ifdef CONFIG_THREAD_CUSTOM_DATA
+	/* Initialize custom data field (value is opaque to kernel) */
+	thread->custom_data = NULL;
+#endif
+	thread->callee_saved.key = 0;
+	thread->callee_saved.preemptive = 0;
+	/* Leave the rest of thread->callee_saved junk */
+
+	thread_monitor_init(thread);
+
+
+    //printk("\nInitial context SP = 0x%x\n", (unsigned long)pStack);
+    thread->callee_saved.r[COOP_REG_RA/sizeof(uint64_t)] = (uint64_t)_thread_entry;
+    thread->callee_saved.r[COOP_REG_MEPC/sizeof(uint64_t)] = (uint64_t)_thread_entry;
+    thread->callee_saved.r[COOP_REG_A0/sizeof(uint64_t)] = (uint64_t)pEntry;
+    thread->callee_saved.r[COOP_REG_A1/sizeof(uint64_t)] = (uint64_t)p1;
+    thread->callee_saved.r[COOP_REG_A2/sizeof(uint64_t)] = (uint64_t)p2;
+    thread->callee_saved.r[COOP_REG_A3/sizeof(uint64_t)] = (uint64_t)p3;
+    thread->callee_saved.r[COOP_REG_SP/sizeof(uint64_t)] =
+        (uint64_t)(pStack + stackSize);
+#ifdef _WIN32
+    LIBH_create_thread(pStack, (unsigned int)stackSize, prio, options);
+#endif
+}
diff --git a/arch/riscv64/core/offsets/offsets.c b/arch/riscv64/core/offsets/offsets.c
new file mode 100644
index 0000000..c1cd125
--- /dev/null
+++ b/arch/riscv64/core/offsets/offsets.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * @brief RISC-V nano kernel structure member offset definition file
+ *
+ * This module is responsible for the generation of the absolute symbols whose
+ * value represents the member offsets for various RISC-V nanokernel
+ * structures.
+ *
+ * All of the absolute symbols defined by this module will be present in the
+ * final microkernel or nanokernel ELF image (due to the linker's reference to
+ * the _OffsetAbsSyms symbol).
+ *
+ * INTERNAL
+ * It is NOT necessary to define the offset for every member of a structure.
+ * Typically, only those members that are accessed by assembly language routines
+ * are defined; however, it doesn't hurt to define all fields for the sake of
+ * completeness.
+ */
+
+#include <gen_offset.h>
+
diff --git a/arch/riscv64/core/swap.S b/arch/riscv64/core/swap.S
new file mode 100644
index 0000000..8ead287
--- /dev/null
+++ b/arch/riscv64/core/swap.S
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2014-2015 Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _ASMLANGUAGE
+
+#include "swap_macros.h"
+
+/**
+ *
+ * @brief Initiate a cooperative context switch
+ *
+ * The _Swap() routine is invoked by various nanokernel services to effect
+ * a cooperative context switch.  Prior to invoking _Swap(), the caller
+ * disables interrupts via nanoCpuIntLock() and the return 'key' is passed as a
+ * parameter to _Swap(). The key is in fact the value stored in the register
+ * operand of a CLRI instruction.
+ *
+ * It stores the intlock key parameter into current->intlock_key.
+
+ * Given that _Swap() is called to effect a cooperative context switch,
+ * the caller-saved integer registers are saved on the stack by the function
+ * call preamble to _Swap(). This creates a custom stack frame that will be
+ * popped when returning from _Swap(), but is not suitable for handling a return
+ * from an exception. Thus, the fact that the thread is pending because of a
+ * cooperative call to _Swap() has to be recorded via the _CAUSE_COOP code in
+ * the relinquish_cause of the thread's tTCS. The _IrqExit()/_FirqExit() code
+ * will take care of doing the right thing to restore the thread status.
+ *
+ * When _Swap() is invoked, we know the decision to perform a context switch or
+ * not has already been taken and a context switch must happen.
+ *
+ * @return may contain a return value setup by a call to fiberRtnValueSet()
+ *
+ * C function prototype:
+ *
+ * unsigned int _Swap (unsigned int key);
+ *
+ */
+
+.section ".text"
+.globl __start
+__start:
+	jal _Cstart;
+
+.section ".text"
+.globl _Swap
+_Swap:
+	_save_context(tp)
+	la s0, _kernel
+	ld s1,_kernel_offset_to_current(s0)     	# s1 = _kernel.current
+	addi s2,s1,_thread_offset_to_callee_saved 	# s2 = &next_thread->callee_saved
+	sd a0,_callee_saved_offset_to_key(s2)        	# _kernel.current->callee_saved.key = fl
+
+        ## Populate default return value
+	lw a1,_k_neg_eagain
+	sd a1, _callee_saved_offset_to_retval(s2)
+
+	## This thread was switched preemptively
+	li a1,0
+	sd a1,_callee_saved_offset_to_preemptive(s2)
+
+	jal _get_next_ready_thread
+	mv s1,a0
+	sd s1,_kernel_offset_to_current(s0)     	# _kernel.current = _get_next_ready_thread()
+	addi tp,s1,_thread_offset_to_callee_saved 	# tp = &next_thread->callee_saved
+
+	ld a0,_callee_saved_offset_to_key(tp)        	# a0 = callee_saved.key
+        jal _arch_irq_unlock                        	# _arch_irq_unlock(callee_saved.key)
+
+	_restore_context(tp)
+	ld t4,_callee_saved_offset_to_preemptive(tp)
+	bnez t4,__swap_preemptive
+__swap_cooperative:
+	ret
+__swap_preemptive:
+	ld t4,COOP_REG_MEPC(tp)
+	jalr t4
+
+##
+#  _IsrWrapper(int idx, void *)
+#       a0 store IRQ index,
+#       a1 equals NULL
+#
+.globl _IsrWrapper
+_IsrWrapper:
+        addi sp,sp,-32
+        sd ra,0(sp)
+        sd s0,8(sp)
+        sd s1,16(sp)
+        sd s2,24(sp)
+
+	# Grab a reference to _kernel in r10 so we can determine the
+	# current irq stack pointer
+	#
+	la a1,_kernel
+
+	# Stash a copy of thread's sp in r12 so that we can put it on the IRQ
+	# stack
+	#
+	mv a2,sp
+
+	# Switch to interrupt stack
+	ld sp,_kernel_offset_to_irq_stack(a1)
+
+	# Store thread stack pointer onto IRQ stack
+	addi sp,sp,-8
+	sd a2,0(sp)
+
+	call run_isr_handler
+
+	ld sp,0(sp)
+
+	# Check reschedule condition 
+	jal _get_next_ready_thread
+	beqz a0,_IsrExit_ending         # _get_next_ready_thread() == 0 goto ending
+
+	## Do not reschedule coop threads (threads that have negative prio)
+	ld s1, _thread_offset_to_prio(a0)
+	blt  s1,zero,_IsrExit_ending
+
+	## Do not reschedule if scheduler is locked
+	ld s1, _thread_offset_to_sched_locked(a0)
+	bne s1,zero,_IsrExit_ending
+
+	## Call into the kernel to see if a scheduling decision is necessary
+	mv s1,a0				# s1 = next_thread
+	jal _is_next_thread_current
+	bne a0,zero,_IsrExit_ending
+
+	## Flag current thread that it was switched preemptively
+	la s0, _kernel
+	ld s0,_kernel_offset_to_current(s0)     	# s0 = _kernel.current
+	addi s2,s0,_thread_offset_to_callee_saved 	# s2 = &next_thread->callee_saved
+	li a0,1
+	sd a0,_callee_saved_offset_to_preemptive(s2)
+
+	# Store IRQ key
+        jal _arch_irq_lock_state        	# a0 = _arch_irq_lock_state()
+        sd a0,_callee_saved_offset_to_key(s2)
+
+	##
+	# Switch to the new thread.
+	#
+	addi tp,s1,_thread_offset_to_callee_saved 	# tp = &next_thread->callee_saved
+
+	ld a0,_callee_saved_offset_to_key(tp)        	# a0 = callee_saved.key
+        jal _arch_irq_unlock                        	# _arch_irq_unlock(callee_saved.key)
+
+	ld t4,_callee_saved_offset_to_preemptive(tp)
+	bnez t4,_IsrExit_ending
+
+	## Next thread was switched cooperative so,set MEPC to ra
+	ld a0,COOP_REG_RA(tp)
+	sd a0,COOP_REG_MEPC(tp)
+
+
+_IsrExit_ending:
+        ld s2,24(sp)
+        ld s1,16(sp)
+        ld s0,8(sp)
+        ld ra,0(sp)
+        addi sp,sp,32
+	ret
diff --git a/arch/riscv64/core/swap_macros.h b/arch/riscv64/core/swap_macros.h
new file mode 100644
index 0000000..f520918
--- /dev/null
+++ b/arch/riscv64/core/swap_macros.h
@@ -0,0 +1,159 @@
+/* swap_macros.h - helper macros for context switch */
+
+/*
+ * Copyright (c) 2014 Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _SWAP_MACROS__H_
+#define _SWAP_MACROS__H_
+
+#define tNANO_FIBER_OFFSET   0
+#define tNANO_TASK_OFFSET    8
+#define tNANO_CURRENT_OFFSET 16
+
+#define _kernel_offset_to_irq_stack    8
+#define _kernel_offset_to_current      16
+
+#define _timeout_sizeof                48 
+#define _thread_offset_to_prio         24
+#define _thread_offset_to_sched_locked 32
+#define _thread_offset_to_callee_saved 96  //_thread_base_sizeof+caller_saved
+
+#define _callee_saved_offset_to_key        256  //(32*sizeof(uint64_t))
+#define _callee_saved_offset_to_retval     264  //(33*sizeof(uint64_t))
+#define _callee_saved_offset_to_preemptive 272  //(34*sizeof(uint64_t))
+
+#define TCS_LINK_OFFSET         0
+#define TCS_FLAGS_OFFSET        8
+#define TCS_INTLOCK_OFFSET      16
+#define TCS_COOP_REGS_OFFSET    24
+
+/**
+ * Saved by callee function registers:
+ *      s0..s11, sp, tp
+ */
+
+/** Return address */
+#define COOP_REG_RA         0//(0*sizeof(uint64_t))
+/** Saved registers */
+#define COOP_REG_S0         8//(1*sizeof(uint64_t))
+#define COOP_REG_S1         16//(2*sizeof(uint64_t))
+#define COOP_REG_S2         24//(3*sizeof(uint64_t))
+#define COOP_REG_S3         32//(4*sizeof(uint64_t))
+#define COOP_REG_S4         40//(5*sizeof(uint64_t))
+#define COOP_REG_S5         48//(6*sizeof(uint64_t))
+#define COOP_REG_S6         56//(7*sizeof(uint64_t))
+#define COOP_REG_S7         64//(8*sizeof(uint64_t))
+#define COOP_REG_S8         72//(9*sizeof(uint64_t))
+#define COOP_REG_S9         80//(10*sizeof(uint64_t))
+#define COOP_REG_S10        88//(11*sizeof(uint64_t))
+#define COOP_REG_S11        96//(12*sizeof(uint64_t))
+/** Stack pointer */
+#define COOP_REG_SP         104//(13*sizeof(uint64_t))
+/** Thread pointer */
+#define COOP_REG_TP         112//(14*sizeof(uint64_t))
+#define COOP_REG_MEPC       COOP_REG_TP//(14*sizeof(uint64_t))
+/** Return values */
+#define COOP_REG_V0         120//(15*sizeof(uint64_t))
+#define COOP_REG_V1         128//(16*sizeof(uint64_t))
+/** Function Arguments */
+#define COOP_REG_A0         136//(17*sizeof(uint64_t))
+#define COOP_REG_A1         144//(18*sizeof(uint64_t))
+#define COOP_REG_A2         152//(19*sizeof(uint64_t))
+#define COOP_REG_A3         160//(20*sizeof(uint64_t))
+#define COOP_REG_A4         168//(21*sizeof(uint64_t))
+#define COOP_REG_A5         176//(22*sizeof(uint64_t))
+#define COOP_REG_A6         184//(23*sizeof(uint64_t))
+#define COOP_REG_A7         192//(24*sizeof(uint64_t))
+/** Temporary registers */
+#define COOP_REG_T0         200//(25*sizeof(uint64_t))
+#define COOP_REG_T1         208//(26*sizeof(uint64_t))
+#define COOP_REG_T2         216//(27*sizeof(uint64_t))
+#define COOP_REG_T3         224//(28*sizeof(uint64_t))
+#define COOP_REG_T4         232//(29*sizeof(uint64_t))
+/** Global pointer */
+#define COOP_REG_GP         240//(30*sizeof(uint64_t))
+
+#define COOP_REGS_TOTAL     32
+#define COOP_STACKFRAME_SIZE (COOP_REGS_TOTAL*sizeof(uint64_t))
+
+
+#define _save_context(TO) \
+  sd ra, COOP_REG_RA(TO); \
+  sd s0, COOP_REG_S0(TO); \
+  sd s1, COOP_REG_S1(TO); \
+  sd s2, COOP_REG_S2(TO); \
+  sd s3, COOP_REG_S3(TO); \
+  sd s4, COOP_REG_S4(TO); \
+  sd s5, COOP_REG_S5(TO); \
+  sd s6, COOP_REG_S6(TO); \
+  sd s7, COOP_REG_S7(TO); \
+  sd s8, COOP_REG_S8(TO); \
+  sd s9, COOP_REG_S9(TO); \
+  sd s10, COOP_REG_S10(TO); \
+  sd s11, COOP_REG_S11(TO); \
+  sd sp, COOP_REG_SP(TO); \
+  sd x16, COOP_REG_V0(TO); \
+  sd x17, COOP_REG_V1(TO); \
+  sd a0, COOP_REG_A0(TO); \
+  sd a1, COOP_REG_A1(TO); \
+  sd a2, COOP_REG_A2(TO); \
+  sd a3, COOP_REG_A3(TO); \
+  sd a4, COOP_REG_A4(TO); \
+  sd a5, COOP_REG_A5(TO); \
+  sd a6, COOP_REG_A6(TO); \
+  sd a7, COOP_REG_A7(TO); \
+  sd t0, COOP_REG_T0(TO); \
+  sd t1, COOP_REG_T1(TO); \
+  sd t2, COOP_REG_T2(TO); \
+  sd t3, COOP_REG_T3(TO); \
+  sd t4, COOP_REG_T4(TO); \
+  sd gp, COOP_REG_GP(TO);
+
+
+#define _restore_context(FROM) \
+  ld ra, COOP_REG_RA(FROM); \
+  ld s0, COOP_REG_S0(FROM); \
+  ld s1, COOP_REG_S1(FROM); \
+  ld s2, COOP_REG_S2(FROM); \
+  ld s3, COOP_REG_S3(FROM); \
+  ld s4, COOP_REG_S4(FROM); \
+  ld s5, COOP_REG_S5(FROM); \
+  ld s6, COOP_REG_S6(FROM); \
+  ld s7, COOP_REG_S7(FROM); \
+  ld s8, COOP_REG_S8(FROM); \
+  ld s9, COOP_REG_S9(FROM); \
+  ld s10, COOP_REG_S10(FROM); \
+  ld s11, COOP_REG_S11(FROM); \
+  ld sp, COOP_REG_SP(FROM); \
+  ld x16, COOP_REG_V0(FROM); \
+  ld x17, COOP_REG_V1(FROM); \
+  ld a0, COOP_REG_A0(FROM); \
+  ld a1, COOP_REG_A1(FROM); \
+  ld a2, COOP_REG_A2(FROM); \
+  ld a3, COOP_REG_A3(FROM); \
+  ld a4, COOP_REG_A4(FROM); \
+  ld a5, COOP_REG_A5(FROM); \
+  ld a6, COOP_REG_A6(FROM); \
+  ld a7, COOP_REG_A7(FROM); \
+  ld t0, COOP_REG_T0(FROM); \
+  ld t1, COOP_REG_T1(FROM); \
+  ld t2, COOP_REG_T2(FROM); \
+  ld t3, COOP_REG_T3(FROM); \
+  ld t4, COOP_REG_T4(FROM); \
+  ld gp, COOP_REG_GP(FROM);
+
+
+#endif /*  _SWAP_MACROS__H_ */
diff --git a/arch/riscv64/defconfig b/arch/riscv64/defconfig
new file mode 100644
index 0000000..e69de29
diff --git a/arch/riscv64/include/kernel_arch_data.h b/arch/riscv64/include/kernel_arch_data.h
new file mode 100644
index 0000000..ef8242b
--- /dev/null
+++ b/arch/riscv64/include/kernel_arch_data.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016 Gnss Sensor Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __KERNEL_ARCH__DATA_H__
+#define __KERNEL_ARCH__DATA_H__
+
+#include <stdint.h>
+#include <toolchain.h>
+#include <sections.h>
+#include <arch/cpu.h>
+
+#ifndef _ASMLANGUAGE
+#include <kernel.h>
+#include <nano_internal.h>
+#include <stdint.h>
+#include <misc/util.h>
+#include <misc/dlist.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _caller_saved {
+	/*
+	 * Nothing here, the exception code puts all the caller-saved
+	 * registers onto the stack.
+	 */
+    int empty_;
+};
+
+typedef struct _caller_saved _caller_saved_t;
+
+struct _callee_saved {
+    uint64_t r[32];
+	/* IRQ status before irq_lock() and call to _Swap() */
+	uint64_t key;
+
+	/* Return value of _Swap() */
+	uint64_t retval;
+
+    /* I actually do not understand where preemptive tasks switch occurs,
+     * so use this flag stores the latest method of switch 0=coop; 1=preemp.
+     * It allows properly switch cooperative/preemtive threads independently
+     * of its priority
+     */
+    uint64_t preemptive;
+};
+
+typedef struct _callee_saved _callee_saved_t;
+
+struct _thread_arch {
+	/* nothing for now */
+    unsigned int empty_;
+};
+
+typedef struct _thread_arch _thread_arch_t;
+
+struct _kernel_arch {
+	/* nothing for now */
+    int empty_;
+};
+
+typedef struct _kernel_arch _kernel_arch_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __KERNEL_ARCH__DATA_H__ */
diff --git a/arch/riscv64/include/kernel_arch_func.h b/arch/riscv64/include/kernel_arch_func.h
new file mode 100644
index 0000000..55046ab
--- /dev/null
+++ b/arch/riscv64/include/kernel_arch_func.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 Gnss Sensor Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * @brief Private kernel definitions
+ *
+ * This file contains private kernel function/macro definitions and various
+ * other definitions for the Nios II processor architecture.
+ *
+ * This file is also included by assembly language files which must #define
+ * _ASMLANGUAGE before including this header file.  Note that kernel
+ * assembly source files obtains structure offset values via "absolute
+ * symbols" in the offsets.o module.
+ */
+
+#ifndef _kernel_arch_func__h_
+#define _kernel_arch_func__h_
+
+#include <stdint.h>
+#include <toolchain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ASMLANGUAGE
+
+void nano_cpu_idle(void);
+void nano_cpu_atomic_idle(unsigned int key);
+
+extern char _interrupt_stack[];
+
+static ALWAYS_INLINE void nanoArchInit(void)
+{
+	_kernel.irq_stack = _interrupt_stack + CONFIG_ISR_STACK_SIZE;
+}
+
+static ALWAYS_INLINE void
+_set_thread_return_value(struct k_thread *thread, unsigned int value)
+{
+	thread->callee_saved.retval = value;
+}
+
+static inline void _IntLibInit(void)
+{
+	/* No special initialization of the interrupt subsystem required */
+}
+
+FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
+					  const NANO_ESF * esf);
+
+#define _is_in_isr() (_kernel.nested != 0)
+
+#endif /* _ASMLANGUAGE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _kernel_arch_func__h_ */
diff --git a/arch/riscv64/include/kernel_event_logger_arch.h b/arch/riscv64/include/kernel_event_logger_arch.h
new file mode 100644
index 0000000..b6b8e67
--- /dev/null
+++ b/arch/riscv64/include/kernel_event_logger_arch.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * @brief Kernel event logger support for ARM
+ */
+
+#ifndef __KERNEL_EVENT_LOGGER_ARCH_H__
+#define __KERNEL_EVENT_LOGGER_ARCH_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Get the identification of the current interrupt.
+ *
+ * This routine obtain the key of the interrupt that is currently processed
+ * if it is called from a ISR context.
+ *
+ * @return The key of the interrupt that is currently being processed.
+ */
+int _sys_current_irq_key_get(void)
+{
+	return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __KERNEL_EVENT_LOGGER_ARCH_H__ */
diff --git a/arch/riscv64/include/memaccess.h b/arch/riscv64/include/memaccess.h
new file mode 100644
index 0000000..564762b
--- /dev/null
+++ b/arch/riscv64/include/memaccess.h
@@ -0,0 +1,16 @@
+/**
+ * @file Access methods declaration to the memory mapped devices.
+ */
+
+#ifndef _RISCV_CORE_MEMACCESS_H_
+#define _RISCV_CORE_MEMACCESS_H_
+
+#include <stdint.h>
+
+extern uint16_t READ16(volatile uint16_t *addr);
+extern uint32_t READ32(volatile uint32_t *addr);
+extern uint64_t READ64(volatile uint64_t *addr);
+extern void WRITE32(volatile uint32_t *addr, uint32_t val);
+extern void WRITE64(volatile uint64_t *addr, uint64_t val);
+
+#endif  // _RISCV_CORE_MEMACCESS_H_
diff --git a/arch/riscv64/include/offsets_short_arch.h b/arch/riscv64/include/offsets_short_arch.h
new file mode 100644
index 0000000..d28ff64
--- /dev/null
+++ b/arch/riscv64/include/offsets_short_arch.h
@@ -0,0 +1,4 @@
+#ifndef __OFFSETS_SHORT_ARCH_H__
+#define __OFFSETS_SHORT_ARCH_H__
+
+#endif  // __OFFSETS_SHORT_ARCH_H__
diff --git a/arch/riscv64/soc/riscv_gnss/Kbuild b/arch/riscv64/soc/riscv_gnss/Kbuild
new file mode 100644
index 0000000..d035736
--- /dev/null
+++ b/arch/riscv64/soc/riscv_gnss/Kbuild
@@ -0,0 +1,8 @@
+ccflags-y +=-I$(srctree)/arch/riscv64/include
+ccflags-y +=-I$(srctree)/include
+ccflags-y +=-I$(srctree)/include/drivers
+ccflags-y +=-I$(srctree)/drivers
+
+asflags-y := ${ccflags-y}
+
+obj-y += soc.o
diff --git a/arch/riscv64/soc/riscv_gnss/Kconfig.defconfig b/arch/riscv64/soc/riscv_gnss/Kconfig.defconfig
new file mode 100644
index 0000000..31da98c
--- /dev/null
+++ b/arch/riscv64/soc/riscv_gnss/Kconfig.defconfig
@@ -0,0 +1,33 @@
+# Kconfig - Atmel SAM3 family processor configuration options
+
+#
+# Copyright (c) 2016 Intel Corporation.
+# Copyright (c) 2014-2015 Wind River Systems, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+if SOC_RISCV_GNSS
+
+config SOC
+	default riscv_gnss
+
+config NUM_IRQS
+	int
+	default 6
+
+config SYS_CLOCK_HW_CYCLES_PER_SEC
+	int
+	default 40000000
+
+endif # SOC_RISCV_GNSS
diff --git a/arch/riscv64/soc/riscv_gnss/Kconfig.soc b/arch/riscv64/soc/riscv_gnss/Kconfig.soc
new file mode 100644
index 0000000..84626cb
--- /dev/null
+++ b/arch/riscv64/soc/riscv_gnss/Kconfig.soc
@@ -0,0 +1,5 @@
+
+config SOC_RISCV_GNSS
+	bool "RISC-V SOC by Gnss Sensor Ltd"
+	help
+	Synthezable SoC based on open ISA RISC-V.
diff --git a/arch/riscv64/soc/riscv_gnss/Makefile b/arch/riscv64/soc/riscv_gnss/Makefile
new file mode 100644
index 0000000..3caaddb
--- /dev/null
+++ b/arch/riscv64/soc/riscv_gnss/Makefile
@@ -0,0 +1,6 @@
+
+arch-cflags += $(call cc-option,-mthumb -march=rv64ima -Wunused-function -Wint-to-pointer-cast)
+
+KBUILD_AFLAGS += $(arch-cflags)
+KBUILD_CXXFLAGS += $(arch-cflags)
+KBUILD_CFLAGS += $(arch-cflags)
diff --git a/arch/riscv64/soc/riscv_gnss/linker.ld b/arch/riscv64/soc/riscv_gnss/linker.ld
new file mode 100644
index 0000000..6a68292
--- /dev/null
+++ b/arch/riscv64/soc/riscv_gnss/linker.ld
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014-2015 Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * generate a symbol to mark the start of the device initialization objects for
+ * the specified level, then link all of those objects (sorted by priority);
+ * ensure the objects aren't discarded if there is no direct reference to them
+ */
+
+#include <arch/riscv64/linker.ld>
+
diff --git a/arch/riscv64/soc/riscv_gnss/soc.c b/arch/riscv64/soc/riscv_gnss/soc.c
new file mode 100644
index 0000000..72639bd
--- /dev/null
+++ b/arch/riscv64/soc/riscv_gnss/soc.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2016, GNSS Sensor Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * @brief System/hardware module for GNSS RISC-V family processor
+ *
+ * This module provides routines to initialize and support board-level hardware
+ * for the GNSS RISC-V family processor.
+ */
+
+#include <stdint.h>
+#include <errno.h>
+#include <nanokernel.h>
+#include <device.h>
+#include <init.h>
+#include <soc.h>
+#include <misc/printk.h>
+#include <misc/shell.h>
+#include <sw_isr_table.h>
+#include <memaccess.h>
+
+#define SHELL_SOC "soc"
+
+extern void _IsrWrapper(int idx, void *arg);
+
+typedef union DescriptorTableType {
+    union DescriptorItemType {
+        MasterConfigType mst;
+        SlaveConfigType slv;
+    } *item;
+    uint8_t *buf;
+} DescriptorTableType;
+
+const char *const VENDOR_NAME = "GNSS Sensor Ltd.";
+
+const char *const MST_DID_EMPTY_NAME = "Empty master slot";
+const char *const SLV_DID_EMPTY_NAME = "Empty slave slot";
+
+const char *const UNKOWN_ID_NAME = "Unknown";
+
+static const char *const GNSS_SENSOR_MST_DEVICE_NAMES[] = {
+    "Rocket Cached TileLink",           // 0x500
+    "Rocket Uncached TileLink",         // 0x501
+    "Gaisler Ethernet MAC with DMA",    // 0x502
+    "Gaisler Ethernet EDCL with DMA",   // 0x503
+    "Reserved",                         // 0x504
+    "RISC-V River CPU",                 // 0x505
+};
+
+static const char *const GNSS_SENSOR_SLV_DEVICE_NAMES[] = {
+    "GNSS Engine stub",         // 0x68
+    "Reserved",                 // 0x69
+    "Reserved",                 // 0x6a
+    "Reserved",                 // 0x6b
+    "Reserved",                 // 0x6c
+    "Reserved",                 // 0x6d
+    "Reserved",                 // 0x6e
+    "Reserved",                 // 0x6f
+    "Reserved",                 // 0x70
+    "Boot ROM",                 // 0x71
+    "FW Image ROM",             // 0x72
+    "Internal SRAM",            // 0x73
+    "Plug'n'Play support",      // 0x74
+    "SD Controller",            // 0x75
+    "Generic GPIO",             // 0x76
+    "RF front-end controller",  // 0x77
+    "GNSS Engine",              // 0x78
+    "GPS FSE",                  // 0x79
+    "Generic UART",             // 0x7a
+    "Accelerometer",            // 0x7b
+    "Gyroscope",                // 0x7c
+    "Interrupt Controller",     // 0x7d
+    "Reserved",                 // 0x7e
+    "Ethernet MAC",             // 0x7f
+    "Debug Support Unit (DSU)", // 0x80
+    "GP Timers"                 // 0x81
+};
+
+/**
+ * @brief Get technology name
+ */
+const char *const get_tech_name(uint32_t tech)
+{
+    switch (tech) {
+    case TECH_INFERRED: return "inferred";
+    case TECH_VIRTEX6: return "Virtex6";
+    case TECH_KINTEX7: return "Kintex7";
+    default:;
+    }
+    return "unknown";
+}
+
+/**
+ * @brief Get device Vendor name by its ID
+ */
+static const char *get_vendor_name(uint16_t vid)
+{
+    if (vid != VENDOR_GNSSSENSOR) {
+        return UNKOWN_ID_NAME;
+    }
+    return VENDOR_NAME;
+}
+
+/**
+ * @brief Get device Name by Vendor ID and Device ID
+ */
+static const char *get_device_name(uint16_t vid, uint16_t did)
+{
+    if (vid != VENDOR_GNSSSENSOR) {
+        return UNKOWN_ID_NAME;
+    }
+    if (did == MST_DID_EMPTY) {
+        return MST_DID_EMPTY_NAME;
+    }
+    if (did == SLV_DID_EMPTY) {
+        return SLV_DID_EMPTY_NAME;
+    }
+    if (did >= GNSSSENSOR_ENGINE_STUB && did <= GNSSSENSOR_GPTIMERS) {
+        return GNSS_SENSOR_SLV_DEVICE_NAMES[did - GNSSSENSOR_ENGINE_STUB];
+    }
+    if (did >= RISCV_CACHED_TILELINK && did <= RISCV_RIVER_CPU) {
+        return GNSS_SENSOR_MST_DEVICE_NAMES[did - RISCV_CACHED_TILELINK];
+    }
+    return UNKOWN_ID_NAME;
+}
+
+/**
+ * @brief Print Plug'n'Play information
+ *
+ * This function reads information from the PNP slave device that is mapped
+ * into hardcoded address __PNP (0xFFFFF000).
+ */
+static int shell_cmd_soc_info(int argc, char *argv[])
+{
+    printk("RISC-V synthesizable SoC platform available for download at:\n");
+    printk("    https://github.com/sergeykhbr/riscv_vhdl\n\n");
+    printk("Author: Sergey Khabarov - sergeykhbr@gmail.com\n");
+    return 0;
+}
+
+/**
+ * @brief Print Plug'n'Play information
+ *
+ * This function reads information from the PNP slave device that is mapped
+ * into hardcoded address __PNP (0xFFFFF000).
+ */
+static int shell_cmd_soc_pnp(int argc, char *argv[])
+{
+    uint32_t slaves_total, tech, hwid;
+    uint16_t vid, did;
+    adr_type xaddr, xmask, xsize;
+    volatile uint32_t *iter;
+    MasterDescrWord mcfg;
+    int mst_cnt=0, slv_cnt=0;
+
+    tech = READ32(&__PNP->tech);
+    slaves_total = (tech >> 8) & 0xff;
+    printk("# RISC-V:  Rocket-Chip demonstration design\n");
+    hwid = READ32(&__PNP->hwid);
+    printk("# HW id:   0x%x\n", hwid);
+    hwid = READ32(&__PNP->fwid);
+    printk("# FW id:   0x%x\n", hwid);
+    printk("# Target technology: %s\n", get_tech_name(tech & 0xFF));
+
+    iter = (volatile uint32_t *)__PNP->cfg_table;
+    mcfg.val = READ32(iter);
+    while (mcfg.bits.descrtype != PNP_CFG_TYPE_INVALID) {
+        if (mcfg.bits.descrtype == PNP_CFG_TYPE_MASTER) {
+            MasterConfigType *pmst = (MasterConfigType *)iter;
+            vid = READ16(&pmst->vid);
+            did = READ16(&pmst->did);
+            printk("# AXI4: mst%d: %s    %s\n", mst_cnt++, 
+                get_vendor_name(vid), get_device_name(vid, did));
+        } else {
+            SlaveConfigType *pslv = (SlaveConfigType *)iter;
+            vid = READ16(&pslv->vid);
+            did = READ16(&pslv->did);
+            printk("# AXI4: slv%d: %s    %s\n", slv_cnt++, 
+                get_vendor_name(vid), get_device_name(vid, did));
+
+            xaddr = READ32(&pslv->xaddr);
+            xmask = READ32(&pslv->xmask);
+            xmask ^= 0xFFFFFFFF;
+            xsize = xmask + 1;
+
+
+            printk("#    %x...%x, size = ",
+                (unsigned long)xaddr, (unsigned long)(xaddr + xmask));
+            if (xsize < 1024) {
+                printk("%d bytes\n", (int)xsize);
+            } else if (xsize < 1024*1024) {
+                printk("%d KB\n", (int)(xsize >> 10));
+            } else {
+                printk("%d MB\n", (int)(xsize >> 20));
+            }
+        }
+
+        iter = (volatile uint32_t *)((uint8_t *)iter + mcfg.bits.descrsize);
+        mcfg.val = READ32(iter);
+    }
+    return 0;
+}
+
+/**
+ * @brief Check hardware target configuration is it inferred or not.
+ *
+ * inferred hardware target is used for RTL simulation of the whole SOC design.
+ */
+uint32_t soc_is_rtl_simulation()
+{
+    uint32_t tech = READ32(&__PNP->tech);
+    return (tech & 0xff) == TECH_INFERRED ? 1: 0;
+}
+
+/**
+ *
+ * @brief perform basic hardware initialization
+ *
+ * Hardware initialized:
+ * - interrupt unit
+ *
+ * RETURNS: N/A
+ */
+static int riscv_gnss_soc_init(struct device *arg)
+{
+    ARG_UNUSED(arg);
+    WRITE64(&__IRQCTRL->isr_table, (uint64_t)_IsrWrapper);
+    WRITE32(&__IRQCTRL->irq_lock, 0);
+    return 0;
+}
+
+struct shell_cmd soc_commands[] = {
+    { "info", shell_cmd_soc_info, "Show SoC RTL download link" },
+    { "pnp", shell_cmd_soc_pnp, "Show Plug'n'Play information" },
+    { NULL, NULL }
+};
+
+SYS_INIT(riscv_gnss_soc_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
+
+SHELL_REGISTER(SHELL_SOC, soc_commands);
diff --git a/arch/riscv64/soc/riscv_gnss/soc.h b/arch/riscv64/soc/riscv_gnss/soc.h
new file mode 100644
index 0000000..9206f41
--- /dev/null
+++ b/arch/riscv64/soc/riscv_gnss/soc.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2016, GNSS Sensor Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file SoC configuration macros for the GNSS Sensor Risc-V family processors.
+ */
+
+#ifndef _RISCV_SOC_GNSS_H_
+#define _RISCV_SOC_GNSS_H_
+
+#include <device.h>
+#include <misc/util.h>
+#include <drivers/rand32.h>
+
+#include "soc_registers.h"
+
+#define VENDOR_GNSSSENSOR        0x00F1
+
+#define MST_DID_EMPTY            0x7755
+#define SLV_DID_EMPTY            0x5577     /// Dummy device
+
+/// Known master device IDs
+#define RISCV_CACHED_TILELINK    0x0500
+#define RISCV_UNCACHED_TILELINK  0x0501
+#define GAISLER_ETH_MAC_MASTER   0x0502
+#define GAISLER_ETH_EDCL_MASTER  0x0503
+#define RISCV_RIVER_CPU          0x0505
+/// Known slave device IDs
+#define GNSSSENSOR_BOOTROM       0x0071     /// Boot ROM Device ID
+#define GNSSSENSOR_FWIMAGE       0x0072     /// FW ROM image Device ID
+#define GNSSSENSOR_SRAM          0x0073     /// Internal SRAM block Device ID
+#define GNSSSENSOR_PNP           0x0074     /// Configuration Registers Module Device ID provided by gnsslib
+#define GNSSSENSOR_SPI_FLASH     0x0075     /// SD-card controller Device ID provided by gnsslib
+#define GNSSSENSOR_GPIO          0x0076     /// General purpose IOs Device ID provided by gnsslib
+#define GNSSSENSOR_RF_CONTROL    0x0077     /// RF front-end controller Device ID provided by gnsslib
+#define GNSSSENSOR_ENGINE        0x0078     /// GNSS Engine Device ID provided by gnsslib
+#define GNSSSENSOR_ENGINE_STUB   0x0068     /// GNSS Engine stub
+#define GNSSSENSOR_FSE_V2        0x0079     /// Fast Search Engines Device ID provided by gnsslib
+#define GNSSSENSOR_UART          0x007a     /// rs-232 UART Device ID
+#define GNSSSENSOR_ACCELEROMETER 0x007b     /// Accelerometer Device ID provided by gnsslib
+#define GNSSSENSOR_GYROSCOPE     0x007c     /// Gyroscope Device ID provided by gnsslib
+#define GNSSSENSOR_IRQCTRL       0x007d     /// Interrupt controller
+#define GNSSSENSOR_ETHMAC        0x007f
+#define GNSSSENSOR_DSU           0x0080
+#define GNSSSENSOR_GPTIMERS      0x0081
+
+#define PNP_CFG_TYPE_INVALID     0
+#define PNP_CFG_TYPE_MASTER      1
+#define PNP_CFG_TYPE_SLAVE       2
+
+#define TECH_INFERRED       0
+#define TECH_VIRTEX6        36
+#define TECH_KINTEX7        49
+
+
+
+#define ADDR_NASTI_SLAVE_FWIMAGE    0x00100000
+#define ADDR_NASTI_SLAVE_SRAM       0x10000000
+#define ADDR_NASTI_SLAVE_GPIO       0x80000000
+#define ADDR_NASTI_SLAVE_UART1      0x80001000
+#define ADDR_NASTI_SLAVE_IRQCTRL    0x80002000
+#define ADDR_NASTI_SLAVE_GNSSENGINE 0x80003000
+#define ADDR_NASTI_SLAVE_RFCTRL     0x80004000
+#define ADDR_NASTI_SLAVE_GPTIMERS   0x80005000
+#define ADDR_NASTI_SLAVE_FSEGPS     0x8000a000
+#define ADDR_NASTI_SLAVE_ETHMAC     0x80040000
+#define ADDR_NASTI_SLAVE_PNP        0xfffff000
+
+/* Interrupts pins assignments */
+#define CFG_IRQ_UNUSED      0
+#define CFG_IRQ_UART1       1
+#define CFG_IRQ_ETH         2
+#define CFG_IRQ_SYS_TIMER   3
+#define CFG_IRQ_MISS_ACCESS 4
+#define CFG_IRQ_GNSS_ENGINE 5
+
+/* Use this general purpose timer as a system timer */
+#define CFG_SYS_TIMER_IDX 0
+
+/* PNP */
+#define PNP_CONFIG_DEFAULT_BYTES 16
+
+/* uart configuration settings */
+#define UART_IRQ_FLAGS 0    // used in console driver
+
+
+#ifndef _ASMLANGUAGE
+
+typedef uint64_t adr_type;
+
+
+typedef void (*IRQ_HANDLER)(void *arg);
+
+
+#define __PNP	((volatile struct pnp_map *)ADDR_NASTI_SLAVE_PNP)
+/** @todo remove hardcoded addresses except __PNP. */
+#define __UART1	((volatile struct uart_map *)ADDR_NASTI_SLAVE_UART1)
+#define __IRQCTRL	((volatile struct irqctrl_map *)ADDR_NASTI_SLAVE_IRQCTRL)
+#define __TIMERS ((volatile struct gptimers_map *)ADDR_NASTI_SLAVE_GPTIMERS)
+
+/** 
+ * @brief Print Plug'n'Play information
+ *
+ * Each devices in a SOC implements sideband signals that are connected to
+ * PNP module. These signals provide such information as Vendor/Device IDs,
+ * memory address and allocated memory range.
+ */
+extern void soc_print_pnp();
+
+/**
+ * @brief Check hardware target configuration is it inferred or not.
+ *
+ * inferred hardware target is used for RTL simulation of the whole SOC design.
+ */
+extern uint32_t soc_is_rtl_simulation();
+
+#endif /* !_ASMLANGUAGE */
+
+#endif /* _RISCV_SOC_GNSS_H_ */
diff --git a/arch/riscv64/soc/riscv_gnss/soc_registers.h b/arch/riscv64/soc/riscv_gnss/soc_registers.h
new file mode 100644
index 0000000..4bbb4d6
--- /dev/null
+++ b/arch/riscv64/soc/riscv_gnss/soc_registers.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016, GNSS Sensor Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file SoC configuration macros for the Atmel SAM3 family processors.
+ *
+ * Refer to the datasheet for more information about these registers.
+ */
+
+#ifndef _RISCV_GNSS_SOC_REGS_H_
+#define _RISCV_GNSS_SOC_REGS_H_
+
+typedef struct MasterDescrWordBits {
+    uint32_t descrsize : 8;
+    uint32_t descrtype : 2;
+    uint32_t rsrv : 14;
+    uint32_t master_idx : 8;
+} MasterDescrWordBits;
+
+typedef union MasterDescrWord {
+    MasterDescrWordBits bits;
+    uint32_t val;
+} MasterDescrWord;
+
+typedef struct MasterConfigType {
+    MasterDescrWord descr;
+    uint16_t did;
+    uint16_t vid;
+} MasterConfigType;
+
+typedef struct SlaveDescrWordBits {
+    uint32_t descrsize : 8;
+    uint32_t descrtype : 2;
+    uint32_t bar_total : 2;
+    uint32_t rsrv1 : 4;
+    uint32_t irq_idx : 8;
+    uint32_t rsrv2 : 8;
+} SlaveDescrWordBits;
+
+typedef union SlaveDescrWord {
+    SlaveDescrWordBits bits;
+    uint32_t val;
+} SlaveDescrWord;
+
+typedef struct SlaveConfigType {
+    SlaveDescrWord descr;
+    uint16_t did;
+    uint16_t vid;
+    uint32_t xmask;
+    uint32_t xaddr;
+} SlaveConfigType;
+
+typedef struct pnp_map {
+    volatile uint32_t hwid;         /// Read only HW ID
+    volatile uint32_t fwid;         /// Read/Write Firmware ID
+    volatile uint32_t tech;         /// Read only technology index
+    volatile uint32_t rsrv1;        /// 
+    volatile uint64_t idt;          /// 
+    volatile uint64_t malloc_addr;  /// debuggind memalloc pointer
+    volatile uint64_t malloc_size;  /// debugging memalloc size
+    volatile uint64_t fwdbg1;       /// FW debug register
+    volatile uint64_t rsrv[2];
+    uint8_t cfg_table[(1 << 12) - 0x40];    /// 0xfffff040: RO: PNP configuration
+} pnp_map;
+
+typedef struct uart_map {
+    volatile uint32_t status;
+    volatile uint32_t scaler;
+    uint32_t rsrv[2];
+    volatile uint32_t data;
+} uart_map;
+
+
+typedef struct irqctrl_map {
+    volatile uint32_t irq_mask;     // 0x00: [RW] 1=disable; 0=enable
+    volatile uint32_t irq_pending;  // 0x04: [RW]
+    volatile uint32_t irq_clear;    // 0x08: [WO]
+    volatile uint32_t irq_rise;     // 0x0C: [WO]
+    volatile uint64_t isr_table;    // 0x10: [RW]
+    volatile uint64_t dbg_cause;    // 0x18: 
+    volatile uint64_t dbg_epc;      // 0x20: 
+    volatile uint32_t irq_lock;     // 0x28: interrupts wait while lock=1
+    volatile uint32_t irq_cause_idx;// 0x2c: 
+} irqctrl_map;
+
+
+typedef struct gptimer_type {
+    volatile uint32_t control;      // [0] = count_ena; [1] = irq_ena
+    volatile uint32_t rsv1;
+    volatile uint64_t cur_value;
+    volatile uint64_t init_value;
+} gptimer_type;
+
+typedef struct gptimers_map {
+    volatile uint64_t highcnt;
+    volatile uint32_t pending;
+    uint32_t rsv1[13];
+    gptimer_type tmr[2];
+} gptimer_map;
+
+#endif /* _RISCV_GNSS_SOC_REGS_H_ */
diff --git a/boards/riscv64/riscv_gnss/Kconfig.board b/boards/riscv64/riscv_gnss/Kconfig.board
new file mode 100644
index 0000000..f6662ef
--- /dev/null
+++ b/boards/riscv64/riscv_gnss/Kconfig.board
@@ -0,0 +1,6 @@
+
+config  BOARD_RISCV_GNSS
+        bool "RISC-V based FPGA SoC"
+        depends on SOC_RISCV_GNSS
+	help
+	The RISC-v VHDL FPGA development boards
diff --git a/boards/riscv64/riscv_gnss/Kconfig.defconfig b/boards/riscv64/riscv_gnss/Kconfig.defconfig
new file mode 100644
index 0000000..8e55bc5
--- /dev/null
+++ b/boards/riscv64/riscv_gnss/Kconfig.defconfig
@@ -0,0 +1,22 @@
+
+if BOARD_RISCV_GNSS
+
+config BOARD
+        default riscv_gnss
+
+config CONSOLE
+	def_bool y
+
+config UART_CONSOLE
+	def_bool y
+
+config UART_INTERRUPT_DRIVEN
+	def_bool y
+
+config CONSOLE_HANDLER_SHELL
+	def_bool y
+
+config STDOUT_CONSOLE
+	def_bool y
+
+endif # BOARD_RISCV_GNSS
diff --git a/boards/riscv64/riscv_gnss/Makefile b/boards/riscv64/riscv_gnss/Makefile
new file mode 100644
index 0000000..7414f8c
--- /dev/null
+++ b/boards/riscv64/riscv_gnss/Makefile
@@ -0,0 +1,6 @@
+ccflags-y += -I$(srctree)/include/drivers
+ccflags-y += -I$(srctree)/drivers
+asflags-y := ${ccflags-y}
+
+# Force kbuild to make empty built-in.o if necessary
+obj- := dummy.o
diff --git a/boards/riscv64/riscv_gnss/board.h b/boards/riscv64/riscv_gnss/board.h
new file mode 100644
index 0000000..55029f6
--- /dev/null
+++ b/boards/riscv64/riscv_gnss/board.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __INC_BOARD_H
+#define __INC_BOARD_H
+
+#include <soc.h>
+
+#endif /* __INC_BOARD_H */
diff --git a/boards/riscv64/riscv_gnss/riscv_gnss_defconfig b/boards/riscv64/riscv_gnss/riscv_gnss_defconfig
new file mode 100644
index 0000000..f5ac997
--- /dev/null
+++ b/boards/riscv64/riscv_gnss/riscv_gnss_defconfig
@@ -0,0 +1,39 @@
+CONFIG_RISCV64=y
+CONFIG_SOC_RISCV_GNSS=y
+CONFIG_BOARD_RISCV_GNSS=y
+CONFIG_PRINTK=y
+CONFIG_STDOUT_CONSOLE=y
+CONFIG_ENABLE_SHELL=y
+xCONFIG_KERNEL_DEBUG=y
+CONFIG_CONSOLE=y
+CONFIG_EARLY_CONSOLE=y
+CONFIG_UART_INTERRUPT_DRIVEN=y
+CONFIG_BOOT_BANNER=y
+CONFIG_CONSOLE_HAS_DRIVER=y
+CONFIG_CONSOLE_HANDLER=y
+CONFIG_CONSOLE_HANDLER_SHELL=y
+CONFIG_CONSOLE_HANDLER_SHELL_STACKSIZE=2000
+CONFIG_UART_CONSOLE=y
+CONFIG_UART_CONSOLE_ON_DEV_NAME="UART_0"
+CONFIG_NUM_COOP_PRIORITIES=16
+CONFIG_NUM_PREEMPT_PRIORITIES=15
+CONFIG_ISR_STACK_SIZE=2048
+CONFIG_PRIORITY_CEILING=0
+CONFIG_NUM_IRQS=6
+CONFIG_SYS_CLOCK_EXISTS=y
+CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=40000000
+CONFIG_SYS_CLOCK_TICKS_PER_SEC=200
+CONFIG_NANO_TIMEOUTS=y
+CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
+CONFIG_SYSTEM_WORKQUEUE_PRIORITY=-1
+CONFIG_OFFLOAD_WORKQUEUE_STACK_SIZE=2048
+CONFIG_OFFLOAD_WORKQUEUE_PRIORITY=-1
+CONFIG_KERNEL_EVENT_LOGGER_BUFFER_SIZE=128
+CONFIG_MAIN_THREAD_PRIORITY=0
+CONFIG_MAIN_STACK_SIZE=2048
+CONFIG_IDLE_STACK_SIZE=1024
+CONFIG_SYSTEM_CLOCK_INIT_PRIORITY=0
+CONFIG_KERNEL_INIT_PRIORITY_DEFAULT=40
+CONFIG_ERRNO=y
+CONFIG_NUM_MBOX_ASYNC_MSGS=10
+CONFIG_NUM_PIPE_ASYNC_MSGS=10
diff --git a/drivers/console/shells/kernel_service.c b/drivers/console/shells/kernel_service.c
index 30bf90d..80b96a6 100644
--- a/drivers/console/shells/kernel_service.c
+++ b/drivers/console/shells/kernel_service.c
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <kernel_version.h>
 #include <misc/printk.h>
 #include <misc/shell.h>
 #include <init.h>
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 6bfd267..7b2d020 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -87,4 +87,6 @@ source "drivers/serial/Kconfig.cc32xx"
 
 source "drivers/serial/Kconfig.cmsdk_apb"
 
+source "drivers/serial/Kconfig.gnss"
+
 endif
diff --git a/drivers/serial/Kconfig.gnss b/drivers/serial/Kconfig.gnss
new file mode 100644
index 0000000..9465075
--- /dev/null
+++ b/drivers/serial/Kconfig.gnss
@@ -0,0 +1,7 @@
+menuconfig UART_RISCV_GNSS
+	bool "RISC-V GNSS board UART driver"
+	default y
+	help
+	Enable the UART driver, built in generic CPU designs generated from
+	VHDL.
+
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 13d56c3..d3366be 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_UART_NRF5)         += uart_nrf5.o
 obj-$(CONFIG_UART_ALTERA_JTAG)  += uart_altera_jtag.o
 obj-$(CONFIG_UART_CC32XX)	+= uart_cc32xx.o
 obj-$(CONFIG_UART_CMSDK_APB)	+= uart_cmsdk_apb.o
+obj-$(CONFIG_UART_RISCV_GNSS)	+= uart_gnss.o
diff --git a/drivers/serial/uart_gnss.c b/drivers/serial/uart_gnss.c
new file mode 100644
index 0000000..d39af24
--- /dev/null
+++ b/drivers/serial/uart_gnss.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2016, GNSS Sensor Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <nanokernel.h>
+#include <arch/cpu.h>
+#include <sections.h>
+#include <misc/__assert.h>
+#include <stdint.h>
+#include <misc/util.h>
+#include <string.h>
+#include <board.h>
+#include <init.h>
+#include <uart.h>
+#include <irq.h>
+#include <memaccess.h>
+
+#define UART_STATUS_TX_FULL     0x00000001
+#define UART_STATUS_TX_EMPTY    0x00000002
+#define UART_STATUS_RX_FULL     0x00000010
+#define UART_STATUS_RX_EMPTY    0x00000020
+#define UART_STATUS_ERR_PARITY  0x00000100
+#define UART_STATUS_ERR_STOPBIT 0x00000200
+#define UART_CONTROL_RX_IRQ_ENA 0x00002000
+#define UART_CONTROL_TX_IRQ_ENA 0x00004000
+#define UART_CONTROL_PARITY_ENA 0x00008000
+
+
+static struct uart_driver_api uart_gnss_driver_api;
+/* Device data structure */
+struct uart_gnss_dev_data_t {
+	uint32_t baud_rate;	/* Baud rate */
+
+#ifdef CONFIG_UART_INTERRUPT_DRIVEN
+	uart_irq_callback_t     cb;     /**< Callback function pointer */
+#endif
+};
+
+static struct uart_gnss_dev_data_t uart_gnss_dev_data_0 = {
+	115200,  // .baud_rate
+    NULL
+};
+
+
+/**
+ * @brief Interrupt service routine.
+ *
+ * This simply calls the callback function, if one exists.
+ *
+ * @param arg Argument to ISR.
+ *
+ * @return N/A
+ */
+void uart_gnss_isr(void *arg) {
+    struct device *dev = (struct device *)arg;
+    struct uart_gnss_dev_data_t *data =
+        (struct uart_gnss_dev_data_t *)dev->driver_data;
+    if (data->cb) {
+        data->cb(dev);
+    }
+}
+
+/*
+ * @brief Output a character to serial port
+ *
+ * @param dev UART device struct
+ * @param c character to output
+ */
+unsigned char uart_gnss_poll_out(struct device *dev, unsigned char c)
+{
+	/* wait for transmitter to ready to accept a character */
+    uint32_t status = READ32(&__UART1->status);
+	while (status & UART_STATUS_TX_FULL) {
+        status = READ32(&__UART1->status);
+	}
+	WRITE32(&__UART1->data, c);
+	return c;
+}
+
+static int uart_gnss_poll_in(struct device *dev, unsigned char *c)
+{
+	return -ENOTSUP;
+
+}
+
+/**
+ * @brief Read data from FIFO
+ *
+ * @param dev UART device struct
+ * @param rx_data Pointer to data container
+ * @param size Container size
+ *
+ * @return Number of bytes read
+ */
+static int uart_gnss_fifo_read(struct device *dev, uint8_t *rx_data,
+				    const int size)
+{
+	uint32_t status = READ32(&__UART1->status);
+	uint8_t num_rx = 0;
+
+	while ((size - num_rx > 0) && ((status & UART_STATUS_RX_EMPTY) == 0)) {
+		rx_data[num_rx++] = (uint8_t)READ32(&__UART1->data);
+        status = READ32(&__UART1->status);
+	}
+
+	return num_rx;
+}
+
+void uart_gnss_irq_tx_enable(struct device *dev) {
+	uint32_t status = READ32(&__UART1->status);
+    status |= UART_CONTROL_TX_IRQ_ENA;
+    WRITE32(&__UART1->status, status);
+}
+
+void uart_gnss_irq_tx_disable(struct device *dev) {
+	uint32_t status = READ32(&__UART1->status);
+    status &= ~UART_CONTROL_TX_IRQ_ENA;
+    WRITE32(&__UART1->status, status);
+}
+
+void uart_gnss_irq_rx_enable(struct device *dev) {
+	uint32_t status = READ32(&__UART1->status);
+    status |= UART_CONTROL_RX_IRQ_ENA;
+    WRITE32(&__UART1->status, status);
+}
+
+void uart_gnss_irq_rx_disable(struct device *dev) {
+	uint32_t status = READ32(&__UART1->status);
+    status &= ~UART_CONTROL_RX_IRQ_ENA;
+    WRITE32(&__UART1->status, status);
+}
+
+int uart_gnss_irq_tx_empty(struct device *dev) {
+	uint32_t status = READ32(&__UART1->status);
+	return ((status & UART_STATUS_TX_EMPTY) ? 1: 0);
+}
+
+/**
+ * @brief Check if Rx IRQ has been raised
+ *
+ * @param dev UART device struct
+ *
+ * @return 1 if an IRQ is ready, 0 otherwise
+ */
+static int uart_gnss_irq_rx_ready(struct device *dev)
+{
+	uint32_t status = READ32(&__UART1->status);
+
+	return ((status & UART_STATUS_RX_EMPTY) ? 0: 1);
+}
+
+
+/**
+ * @brief Check if Tx or Rx IRQ is pending
+ *
+ * @param dev UART device struct
+ *
+ * @return 1 if a Tx or Rx IRQ is pending, 0 otherwise
+ */
+static int uart_gnss_irq_is_pending(struct device *dev)
+{
+	/* Look only at Tx and Rx data interrupt flags */
+	return uart_gnss_irq_rx_ready(dev);
+}
+
+
+/**
+ * @brief Update IRQ status
+ *
+ * @param dev UART device struct
+ *
+ * @return Always 1
+ */
+static int uart_gnss_irq_update(struct device *dev)
+{
+	return 1;
+}
+
+/**
+ * @brief Set the callback function pointer for IRQ.
+ *
+ * @param dev UART device struct
+ * @param cb Callback function pointer.
+ *
+ * @return N/A
+ */
+ static void uart_gnss_irq_callback_set(struct device *dev,
+                                        uart_irq_callback_t cb)
+{
+	struct uart_gnss_dev_data_t * const dev_data = dev->driver_data;
+	dev_data->cb = cb;
+}
+
+static struct uart_driver_api uart_gnss_driver_api = {
+	uart_gnss_poll_in,  // poll_in
+	uart_gnss_poll_out, // poll_out
+	NULL,//int (*err_check)(struct device *dev);
+
+#ifdef CONFIG_UART_INTERRUPT_DRIVEN
+	NULL,//int (*fifo_fill)(struct device *dev, const uint8_t *tx_data, int len);
+	uart_gnss_fifo_read,
+	uart_gnss_irq_tx_enable,
+	uart_gnss_irq_tx_disable,
+	NULL,//int (*irq_tx_ready)(struct device *dev);
+	uart_gnss_irq_rx_enable,
+	uart_gnss_irq_rx_disable,
+	uart_gnss_irq_tx_empty,
+	uart_gnss_irq_rx_ready,
+	NULL,//void (*irq_err_enable)(struct device *dev);
+	NULL,//void (*irq_err_disable)(struct device *dev);
+	uart_gnss_irq_is_pending,
+	uart_gnss_irq_update,
+    uart_gnss_irq_callback_set,
+#endif
+
+#ifdef CONFIG_UART_LINE_CTRL
+	NULL,//int (*line_ctrl_set)(struct device *dev, uint32_t ctrl, uint32_t val);
+#endif
+
+#ifdef CONFIG_UART_DRV_CMD
+	NULL,//int (*drv_cmd)(struct device *dev, uint32_t cmd, uint32_t p);
+#endif
+};
+
+/**
+ * @brief Initialize fake serial port
+ *
+ * @param dev UART device struct
+ *
+ * @return DEV_OK
+ */
+static int uart_gnss_init(struct device *dev)
+{
+	dev->driver_api = &uart_gnss_driver_api;
+    dev->driver_data = &uart_gnss_dev_data_0;
+
+    // Speed-up RTL simulation avoidig long polling of the status register.
+    if (soc_is_rtl_simulation() != 0) {
+        WRITE32(&__UART1->scaler, 20);
+    } else {
+        WRITE32(&__UART1->scaler, CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC/115200/2);
+    }
+
+#ifdef CONFIG_UART_INTERRUPT_DRIVEN
+    uart_gnss_irq_rx_enable(dev);
+	IRQ_CONNECT(CFG_IRQ_UART1, CFG_IRQ_UART1, uart_gnss_isr, dev, UART_IRQ_FLAGS);
+	irq_enable(CFG_IRQ_UART1);
+#endif
+	return 0;
+}
+
+
+DEVICE_INIT(uart_gnss0, "UART_0", &uart_gnss_init,
+			NULL, NULL,
+			PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index 205407c..b2a1c54 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_HPET_TIMER) += hpet.o
 obj-$(CONFIG_LOAPIC_TIMER) += loapic_timer.o
 obj-$(CONFIG_ARCV2_TIMER) += arcv2_timer0.o
 obj-$(CONFIG_ALTERA_AVALON_TIMER) += altera_avalon_timer.o
+obj-$(CONFIG_RISCV_SYSTIMER) += riscv_systimer.o
 
 _CORTEX_M_SYSTICK_AND_GDB_INFO_yy = y
 obj-$(CONFIG_CORTEX_M_SYSTICK) += cortex_m_systick.o
diff --git a/drivers/timer/riscv_systimer.c b/drivers/timer/riscv_systimer.c
new file mode 100644
index 0000000..469be9a
--- /dev/null
+++ b/drivers/timer/riscv_systimer.c
@@ -0,0 +1,148 @@
+#include <nanokernel.h>
+#include <arch/cpu.h>
+#include <device.h>
+#include <drivers/system_timer.h>
+#include <soc.h>
+#include <memaccess.h>
+
+/* running total of timer count */
+static uint32_t __noinit cycles_per_tick;
+static uint32_t accumulated_cycle_count;
+
+#define GPTIMER_CONTROL_COUNT_ENA   0x1
+#define GPTIMER_CONTROL_IRQ_ENA     0x2
+
+/**
+ *
+ * @brief Read the platform's timer hardware
+ *
+ * This routine returns the current time in terms of timer hardware clock
+ * cycles.
+ *
+ * @return up counter of elapsed clock cycles
+ *
+ * \INTERNAL WARNING
+ * If this routine is ever enhanced to return all 64 bits of the counter
+ * it will need to call _hpetMainCounterAtomic().
+ */
+
+uint32_t k_cycle_get_32(void)
+{
+    //return (uint32_t)READ64(&__TIMERS->tmr[CFG_SYS_TIMER_IDX].cur_value);
+	return (uint32_t)READ64(&__TIMERS->highcnt);
+}
+
+uint64_t k_cycle_get_64(void)
+{
+	return READ64(&__TIMERS->highcnt);
+}
+
+#if defined(CONFIG_SYSTEM_CLOCK_DISABLE)
+/**
+ *
+ * @brief Stop announcing ticks into the kernel
+ *
+ * This routine disables timer interrupt generation and delivery.
+ * Note that the timer's counting cannot be stopped by software.
+ *
+ * @return N/A
+ */
+void sys_clock_disable(void)
+{
+	unsigned int key;  /* interrupt lock level */
+	uint32_t control; /* timer control register value */
+
+	key = irq_lock();
+
+	/* disable interrupt generation */
+
+	control = timer0_control_register_get();
+	timer0_control_register_set(control & ~_ARC_V2_TMR_CTRL_IE);
+
+	irq_unlock(key);
+
+	/* disable interrupt in the interrupt controller */
+
+	irq_disable(CONFIG_ARCV2_TIMER0_INT_LVL);
+}
+#endif /* CONFIG_SYSTEM_CLOCK_DISABLE */
+
+
+#ifdef CONFIG_TICKLESS_IDLE
+static INLINE void update_accumulated_count(void)
+{
+	accumulated_cycle_count += (_sys_idle_elapsed_ticks * cycles_per_tick);
+}
+#else /* CONFIG_TICKLESS_IDLE */
+static INLINE void update_accumulated_count(void)
+{
+	accumulated_cycle_count += cycles_per_tick;
+}
+#endif /* CONFIG_TICKLESS_IDLE */
+
+/**
+ *
+ * @brief System clock periodic tick handler
+ *
+ * This routine handles the system clock periodic tick interrupt. It always
+ * announces one tick.
+ *
+ * @return N/A
+ */
+void _timer_int_handler(void *unused)
+{
+	ARG_UNUSED(unused);
+
+	/* clear the interrupt by writing 0 to IP bit of the control register */
+    WRITE32(&__IRQCTRL->irq_clear, (1u << CFG_IRQ_SYS_TIMER));
+    WRITE32(&__TIMERS->pending, 0);
+
+#if defined(CONFIG_TICKLESS_IDLE)
+	timer0_limit_register_set(cycles_per_tick - 1);
+
+	_sys_idle_elapsed_ticks = 1;
+#endif
+
+	update_accumulated_count();
+	_sys_clock_tick_announce();
+}
+
+/*
+ * @brief initialize the tickless idle feature
+ *
+ * This routine initializes the tickless idle feature.
+ *
+ * @return N/A
+ */
+static void tickless_idle_init(void) {}
+
+int _sys_clock_driver_init(struct device *device) {
+	ARG_UNUSED(device);
+
+	/* ensure that the timer will not generate interrupts */
+    WRITE32(&__TIMERS->tmr[CFG_SYS_TIMER_IDX].control, 0);
+
+    sys_clock_hw_cycles_per_tick = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC /
+                                    sys_clock_ticks_per_sec;
+	cycles_per_tick = sys_clock_hw_cycles_per_tick;
+    accumulated_cycle_count = 0;
+
+	IRQ_CONNECT(CFG_IRQ_SYS_TIMER, 0, _timer_int_handler, 0, 0);
+
+	/*
+	 * Set the reload value to achieve the configured tick rate, enable the
+	 * counter and interrupt generation.
+	 */
+
+	tickless_idle_init();
+
+    WRITE64(&__TIMERS->tmr[CFG_SYS_TIMER_IDX].init_value, cycles_per_tick - 1);
+    WRITE32(&__TIMERS->tmr[CFG_SYS_TIMER_IDX].control, 
+        GPTIMER_CONTROL_COUNT_ENA | GPTIMER_CONTROL_IRQ_ENA);
+
+	/* everything has been configured: safe to enable the interrupt */
+
+	irq_enable(CFG_IRQ_SYS_TIMER);
+
+    return 0;
+}
diff --git a/include/arch/cpu.h b/include/arch/cpu.h
index 11f5b8e..513f101 100644
--- a/include/arch/cpu.h
+++ b/include/arch/cpu.h
@@ -27,6 +27,8 @@
 #include <arch/arc/arch.h>
 #elif defined(CONFIG_NIOS2)
 #include <arch/nios2/arch.h>
+#elif defined(CONFIG_RISCV64)
+#include <arch/riscv64/arch.h>
 #else
 #error "Unknown Architecture"
 #endif
diff --git a/include/arch/riscv64/arch.h b/include/arch/riscv64/arch.h
new file mode 100644
index 0000000..1dc50b5
--- /dev/null
+++ b/include/arch/riscv64/arch.h
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2014 Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * @brief RISC-V specific nanokernel interface header
+ *
+ * This header contains the ARC specific nanokernel interface.  It is
+ * included by the nanokernel interface architecture-abstraction header
+ * (nanokernel/cpu.h)
+ */
+
+#ifndef _RISCV_ARCH__H_
+#define _RISCV_ARCH__H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* APIs need to support non-byte addressible architectures */
+
+#define OCTET_TO_SIZEOFUNIT(X) (X)
+#define SIZEOFUNIT_TO_OCTET(X) (X)
+
+#include <sw_isr_table.h>
+#include <stdint.h>
+#include <toolchain.h>
+#include "asm_inline.h"
+
+#define STACK_ALIGN  8
+
+#ifdef _ASMLANGUAGE
+
+
+#else // !_ASMLANGUAGE
+/** interrupt/exception/error related definitions */
+typedef void (*NANO_EOI_GET_FUNC) (void *);
+
+/**
+ * @brief Disable all interrupts on the CPU (inline)
+ *
+ * This routine disables interrupts.  It can be called from either interrupt,
+ * task or fiber level.  This routine returns an architecture-dependent
+ * lock-out key representing the "interrupt disable state" prior to the call;
+ * this key can be passed to irq_unlock() to re-enable interrupts.
+ *
+ * The lock-out key should only be used as the argument to the irq_unlock()
+ * API.  It should never be used to manually re-enable interrupts or to inspect
+ * or manipulate the contents of the source register.
+ *
+ * This function can be called recursively: it will return a key to return the
+ * state of interrupt locking to the previous level.
+ *
+ * WARNINGS
+ * Invoking a kernel routine with interrupts locked may result in
+ * interrupts being re-enabled for an unspecified period of time.  If the
+ * called routine blocks, interrupts will be re-enabled while another
+ * thread executes, or while the system is idle.
+ *
+ * The "interrupt disable state" is an attribute of a thread.  Thus, if a
+ * fiber or task disables interrupts and subsequently invokes a kernel
+ * routine that causes the calling thread to block, the interrupt
+ * disable state will be restored when the thread is later rescheduled
+ * for execution.
+ *
+ * @return An architecture-dependent lock-out key representing the
+ * "interrupt disable state" prior to the call.
+ *
+ */
+
+extern unsigned int _arch_irq_lock(void);
+
+
+/**
+ *
+ * @brief Enable all interrupts on the CPU (inline)
+ *
+ * This routine re-enables interrupts on the CPU.  The @a key parameter
+ * is an architecture-dependent lock-out key that is returned by a previous
+ * invocation of irq_lock().
+ *
+ * This routine can be called from either interrupt, task or fiber level.
+ *
+ * @return N/A
+ *
+ */
+
+extern void _arch_irq_unlock(unsigned int key);
+
+/**
+ *
+ * @brief Read interrupts state on the CPU (inline)
+ *
+ * This routine check interrupts on the CPU.
+  * This routine can be called from either interrupt, task or fiber level.
+ *
+ * @return N/A
+ *
+ */
+
+extern unsigned int _arch_irq_lock_state();
+
+/**
+ *
+ * @brief Enable an interrupt line
+ *
+ * Clear possible pending interrupts on the line, and enable the interrupt
+ * line. After this call, the CPU will receive interrupts for the specified
+ * <irq>.
+ *
+ * @return N/A
+ */
+extern void _arch_irq_enable(unsigned int irq);
+
+/**
+ *
+ * @brief Disable an interrupt line
+ *
+ * Disable an interrupt line. After this call, the CPU will stop receiving
+ * interrupts for the specified <irq>.
+ *
+ * @return N/A
+ */
+extern void _arch_irq_disable(unsigned int irq);
+
+/**
+ * Configure a dynamic interrupt.
+ *
+ * @param irq IRQ line number
+ * @param priority Interrupt priority
+ * @param routine Interrupt service routine
+ * @param parameter ISR parameter
+ * @param flags Arch-specific IRQ configuration flags
+ *
+ * @return The vector assigned to this interrupt
+ */
+int _arch_irq_connect_dynamic(unsigned int irq, unsigned int priority,
+			     void (*routine)(void *parameter), void *parameter,
+			     uint32_t flags);
+
+
+/**
+ * Configure a static interrupt.
+ *
+ * All arguments must be computable by the compiler at build time; if this
+ * can't be done use irq_connect_dynamic() instead.
+ *
+ * Internally this function does a few things:
+ *
+ * 1. The enum statement has no effect but forces the compiler to only
+ * accept constant values for the irq_p parameter, very important as the
+ * numerical IRQ line is used to create a named section.
+ *
+ * 2. An instance of _IsrTableEntry is created containing the ISR and its
+ * parameter. If you look at how _sw_isr_table is created, each entry in the
+ * array is in its own section named by the IRQ line number. What we are doing
+ * here is to override one of the default entries (which points to the
+ * spurious IRQ handler) with what was supplied here.
+ *
+ * 3. The priority level for the interrupt is configured by a call to
+ * _irq_priority_set()
+ *
+ * @param irq_p IRQ line number
+ * @param priority_p Interrupt priority
+ * @param isr_p Interrupt service routine
+ * @param isr_param_p ISR parameter
+ * @param flags_p IRQ triggering options (currently unused)
+ *
+ * @return The vector assigned to this interrupt
+ */
+#define _ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
+	_arch_irq_connect_dynamic(irq_p, priority_p, isr_p, isr_param_p, \
+				  flags_p)
+
+
+
+/**
+ * The NANO_SOFT_IRQ macro must be used as the value for the @a irq parameter
+ * to NANO_CPU_INT_REGSITER when connecting to an interrupt that does not
+ * correspond to any IRQ line (such as spurious vector or SW IRQ)
+ */
+#define NANO_SOFT_IRQ	((unsigned int) (-1))
+
+/**
+ * @brief Nanokernel Exception Stack Frame
+ *
+ * A pointer to an "exception stack frame" (ESF) is passed as an argument
+ * to exception handlers registered via nanoCpuExcConnect().  As the system
+ * always operates at ring 0, only the EIP, CS and EFLAGS registers are pushed
+ * onto the stack when an exception occurs.
+ *
+ * The exception stack frame includes the volatile registers (EAX, ECX, and
+ * EDX) as well as the 5 non-volatile registers (EDI, ESI, EBX, EBP and ESP).
+ * Those registers are pushed onto the stack by _ExcEnt().
+ */
+
+typedef struct nanoEsf {
+	unsigned int esp;
+	unsigned int ebp;
+	unsigned int ebx;
+	unsigned int esi;
+	unsigned int edi;
+	unsigned int edx;
+	unsigned int eax;
+	unsigned int ecx;
+	unsigned int errorCode;
+	unsigned int eip;
+	unsigned int cs;
+	unsigned int eflags;
+} NANO_ESF;
+
+/**
+ * @brief Nanokernel "interrupt stack frame" (ISF)
+ *
+ * An "interrupt stack frame" (ISF) as constructed by the processor
+ * and the interrupt wrapper function _IntEnt().  As the system always operates
+ * at ring 0, only the EIP, CS and EFLAGS registers are pushed onto the stack
+ * when an interrupt occurs.
+ *
+ * The interrupt stack frame includes the volatile registers EAX, ECX, and EDX
+ * pushed on the stack by _IntEnt().
+ */
+
+typedef struct nanoIsf {
+	unsigned int edx;
+	unsigned int ecx;
+	unsigned int eax;
+	unsigned int eip;
+	unsigned int cs;
+	unsigned int eflags;
+} NANO_ISF;
+
+
+/*
+ * Reason codes passed to both _NanoFatalErrorHandler()
+ * and _SysFatalErrorHandler().
+ */
+
+/** Unhandled exception/interrupt */
+#define _NANO_ERR_SPURIOUS_INT		 (0)
+/** Page fault */
+#define _NANO_ERR_PAGE_FAULT		 (1)
+/** General protection fault */
+#define _NANO_ERR_GEN_PROT_FAULT	 (2)
+/** Invalid task exit */
+#define _NANO_ERR_INVALID_TASK_EXIT  (3)
+/** Stack corruption detected */
+#define _NANO_ERR_STACK_CHK_FAIL	 (4)
+/** Kernel Allocation Failure */
+#define _NANO_ERR_ALLOCATION_FAIL    (5)
+/** Unhandled exception */
+#define _NANO_ERR_CPU_EXCEPTION		(6)
+
+
+#include <stddef.h>	/* for size_t */
+
+extern void	nano_cpu_idle(void);
+
+/** Nanokernel provided routine to report any detected fatal error. */
+extern FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
+						 const NANO_ESF * pEsf);
+/** User provided routine to handle any detected fatal error post reporting. */
+extern FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
+						const NANO_ESF * pEsf);
+/** Dummy ESF for fatal errors that would otherwise not have an ESF */
+extern const NANO_ESF _default_esf;
+
+#endif  // _ASMLANGUAGE/!_ASMLANGUAGE
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _RISCV_ARCH__H_ */
diff --git a/include/arch/riscv64/asm_inline.h b/include/arch/riscv64/asm_inline.h
new file mode 100644
index 0000000..9724134
--- /dev/null
+++ b/include/arch/riscv64/asm_inline.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ASM_INLINE_PUBLIC_H
+#define _ASM_INLINE_PUBLIC_H
+
+/*
+ * The file must not be included directly
+ * Include kernel.h instead
+ */
+
+#if defined(__GNUC__)
+#include <arch/riscv64/asm_inline_gcc.h>
+#elif defined _WIN32
+#include <arch/riscv64/asm_inline_cl.h>
+#else
+#include <arch/riscv64/asm_inline_other.h>
+#endif
+
+#endif /* _ASM_INLINE_PUBLIC_H */
diff --git a/include/arch/riscv64/asm_inline_cl.h b/include/arch/riscv64/asm_inline_cl.h
new file mode 100644
index 0000000..8a67967
--- /dev/null
+++ b/include/arch/riscv64/asm_inline_cl.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Either public functions or macros or invoked by public functions */
+
+#ifndef _ASM_INLINE_GCC_PUBLIC_CL_H
+#define _ASM_INLINE_GCC_PUBLIC_CL_H
+
+#include <stdint.h>
+#include <toolchain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The file must not be included directly
+ * Include arch/cpu.h instead
+ */
+
+
+/**
+ *
+ * @brief find least significant bit set in a 32-bit word
+ *
+ * This routine finds the first bit set starting from the least significant bit
+ * in the argument passed in and returns the index of that bit.  Bits are
+ * numbered starting at 1 from the least significant bit.  A return value of
+ * zero indicates that the value passed is zero.
+ *
+ * @return least significant bit set, 0 if @a op is 0
+ */
+
+static ALWAYS_INLINE unsigned int find_lsb_set(uint32_t op)
+{
+	unsigned int ret = 1;
+    if (op == 0) {
+        return 0;
+    }
+	while ((op & 1) == 0) {
+        op >>= 1;
+		ret++;
+	}
+	return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ASM_INLINE_GCC_PUBLIC_CL_H */
diff --git a/include/arch/riscv64/asm_inline_gcc.h b/include/arch/riscv64/asm_inline_gcc.h
new file mode 100644
index 0000000..11a5961
--- /dev/null
+++ b/include/arch/riscv64/asm_inline_gcc.h
@@ -0,0 +1,57 @@
+/* ARM Cortex-M GCC specific public inline assembler functions and macros */
+
+/*
+ * Copyright (c) 2015, Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Either public functions or macros or invoked by public functions */
+
+#ifndef _ASM_INLINE_GCC_PUBLIC_GCC_H
+#define _ASM_INLINE_GCC_PUBLIC_GCC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The file must not be included directly
+ * Include arch/cpu.h instead
+ */
+
+#ifdef _ASMLANGUAGE
+
+#else /* !_ASMLANGUAGE */
+#include <stdint.h>
+
+static ALWAYS_INLINE unsigned int find_lsb_set(uint32_t op)
+{
+	unsigned int ret = 1;
+    if (op == 0) {
+        return 0;
+    }
+	while ((op & 1) == 0) {
+        op >>= 1;
+		ret++;
+	}
+	return ret;
+}
+
+#endif /* _ASMLANGUAGE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ASM_INLINE_GCC_PUBLIC_GCC_H */
diff --git a/include/arch/riscv64/linker.ld b/include/arch/riscv64/linker.ld
new file mode 100644
index 0000000..f4ee018
--- /dev/null
+++ b/include/arch/riscv64/linker.ld
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2014-2015 Wind River Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @brief Common parts of the linker scripts for the RISC-V targets.
+ */
+
+#define _LINKER
+#define _ASMLANGUAGE
+
+#include <autoconf.h>
+#include <sections.h>
+
+#include <linker-defs.h>
+#include <linker-tool.h>
+
+/* physical address of RAM */
+#define ROMABLE_REGION SRAM
+#define RAMABLE_REGION SRAM
+
+MEMORY {
+	SRAM  (rwx) : ORIGIN = CONFIG_SRAM_BASE_ADDRESS,  LENGTH = CONFIG_SRAM_SIZE*1k
+}
+
+SECTIONS {
+	GROUP_START(ROMABLE_REGION)
+
+	SECTION_PROLOGUE(_TEXT_SECTION_NAME,,ALIGN(8)) {
+		_image_rom_start = .;
+		_image_text_start = .;
+
+		*(.text)
+		*(".text.*")
+		*(.gnu.linkonce.t.*)
+
+		_image_text_end = .;
+	} GROUP_LINK_IN(ROMABLE_REGION)
+
+#include <linker/common-rom.ld>
+
+	SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) {
+		*(.rodata)
+		*(".rodata.*")
+		*(.gnu.linkonce.r.*)
+	} GROUP_LINK_IN(ROMABLE_REGION)
+
+	_image_rom_end = .;
+	__data_rom_start = ALIGN(4);	/* XIP imaged DATA ROM start addr */
+
+	GROUP_END(ROMABLE_REGION)
+
+	GROUP_START(RAMABLE_REGION)
+
+	SECTION_PROLOGUE(_DATA_SECTION_NAME,,) {
+
+		_image_ram_start = .;
+		__data_ram_start = .;
+		*(.data)
+		*(".data.*")
+
+
+
+		KEEP(*(._sw_isr_table))
+		KEEP(*(.isr_demux_table))
+
+	} GROUP_LINK_IN(RAMABLE_REGION)
+
+#include <linker/common-ram.ld>
+
+	__data_ram_end = .;
+
+	SECTION_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) {
+		/*
+		 * For performance, BSS section is assumed to be 4 byte aligned and
+		 * a multiple of 4 bytes
+		 */
+		. = ALIGN(4);
+		__bss_start = .;
+		*(.bss)
+		*(".bss.*")
+		COMMON_SYMBOLS
+		/*
+		 * BSP clears this memory in words only and doesn't clear any
+		 * potential left over bytes.
+		 */
+		__bss_end = ALIGN(4);
+	} GROUP_LINK_IN(RAMABLE_REGION)
+
+	SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),) {
+		/*
+		 * This section is used for non-initialized objects that
+		 * will not be cleared during the boot process.
+		 */
+		*(.noinit)
+		*(".noinit.*")
+
+	} GROUP_LINK_IN(RAMABLE_REGION)
+
+	/* Define linker symbols */
+	_image_ram_end = .;
+	_end = .; /* end of image */
+	__bss_num_words = (__bss_end - __bss_start) >> 2;
+
+	GROUP_END(RAMABLE_REGION)
+
+	/* Data Closely Coupled Memory (DCCM) */
+	GROUP_START(DCCM)
+	GROUP_END(DCCM)
+
+	SECTION_PROLOGUE(initlevel_error, (OPTIONAL),)
+	{
+		DEVICE_INIT_UNDEFINED_SECTION()
+	}
+	ASSERT(SIZEOF(initlevel_error) == 0, "Undefined initialization levels used.")
+
+	}
+
diff --git a/include/drivers/console/uart_console.h b/include/drivers/console/uart_console.h
index eea285c..e290886 100644
--- a/include/drivers/console/uart_console.h
+++ b/include/drivers/console/uart_console.h
@@ -27,7 +27,7 @@ extern "C" {
 
 #define MAX_LINE_LEN 256
 struct uart_console_input {
-	int _unused;
+	void *_unused;
 	char line[MAX_LINE_LEN];
 };
 
diff --git a/include/kernel.h b/include/kernel.h
index d49f878..4d322ae 100644
--- a/include/kernel.h
+++ b/include/kernel.h
@@ -29,6 +29,7 @@
 #include <sections.h>
 #include <atomic.h>
 #include <errno.h>
+#include <irq.h>
 #include <misc/__assert.h>
 #include <misc/dlist.h>
 #include <misc/slist.h>
@@ -650,7 +651,11 @@ struct _timeout {
 	sys_dlist_t node;
 	struct k_thread *thread;
 	sys_dlist_t *wait_q;
+#ifdef CONFIG_RISCV64
+	int64_t delta_ticks_from_prev;
+#else
 	int32_t delta_ticks_from_prev;
+#endif
 	_timeout_func_t func;
 };
 
diff --git a/include/kernel_version.h b/include/kernel_version.h
index 9e2ed5e..4392e88 100644
--- a/include/kernel_version.h
+++ b/include/kernel_version.h
@@ -19,6 +19,8 @@
 #ifndef _kernel_version__h_
 #define _kernel_version__h_
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/include/linker-defs.h b/include/linker-defs.h
index f9df709..f6d5478 100644
--- a/include/linker-defs.h
+++ b/include/linker-defs.h
@@ -41,6 +41,8 @@
 /* Nothing yet to include */
 #elif defined(CONFIG_NIOS2)
 /* Nothing yet to include */
+#elif defined(CONFIG_RISCV64)
+/* Nothing yet to include */
 #else
 #error Arch not supported.
 #endif
diff --git a/include/linker-tool-gcc.h b/include/linker-tool-gcc.h
index 782bd2e..3a354e2 100644
--- a/include/linker-tool-gcc.h
+++ b/include/linker-tool-gcc.h
@@ -39,6 +39,8 @@
 	#endif
 #elif defined(CONFIG_NIOS2)
 	OUTPUT_FORMAT("elf32-littlenios2", "elf32-bignios2", "elf32-littlenios2")
+#elif defined(CONFIG_RISCV64)
+	OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
 #else
 	#error Arch not supported.
 #endif
diff --git a/include/misc/shell.h b/include/misc/shell.h
index 158f96f..3a0be96 100644
--- a/include/misc/shell.h
+++ b/include/misc/shell.h
@@ -16,6 +16,9 @@
  * limitations under the License.
  */
 
+#ifndef __MISC_SHELL_H__
+#define __MISC_SHELL_H__
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -126,3 +129,4 @@ static inline int shell_run(struct device *dev) { return 0; }
 }
 #endif
 
+#endif  // __MISC_SHELL_H__
diff --git a/include/toolchain/common.h b/include/toolchain/common.h
index 518c12f..b298969 100644
--- a/include/toolchain/common.h
+++ b/include/toolchain/common.h
@@ -86,6 +86,10 @@
 
     #define PERFOPT_ALIGN .balign 4
 
+  #elif defined(CONFIG_RISCV64)
+
+    #define PERFOPT_ALIGN .balign  8
+
   #else
 
     #error Architecture unsupported
diff --git a/include/toolchain/gcc.h b/include/toolchain/gcc.h
index 4cf420f..c516f02 100644
--- a/include/toolchain/gcc.h
+++ b/include/toolchain/gcc.h
@@ -279,6 +279,11 @@ A##a:
 		",%0"                              \
 		"\n\t.type\t" #name ",%%object" :  : "n"(value))
 
+#elif defined(CONFIG_RISCV64)
+
+#define GEN_ABSOLUTE_SYM(name, value) \
+	__asm__(".globl\t" #name "\n")
+
 #else
 #error processor architecture not supported
 #endif
diff --git a/kernel/unified/atomic_c.c b/kernel/unified/atomic_c.c
index b8f2a19..981765a 100644
--- a/kernel/unified/atomic_c.c
+++ b/kernel/unified/atomic_c.c
@@ -31,6 +31,7 @@
 #include <atomic.h>
 #include <toolchain.h>
 #include <arch/cpu.h>
+#include <irq.h>
 
 /**
  *
diff --git a/kernel/unified/idle.c b/kernel/unified/idle.c
index b6e36a3..83588b1 100644
--- a/kernel/unified/idle.c
+++ b/kernel/unified/idle.c
@@ -154,6 +154,11 @@ void idle(void *unused1, void *unused2, void *unused3)
 		(void)irq_lock();
 		_sys_power_save_idle(_get_next_timeout_expiry());
 
+#ifdef CONFIG_RISCV64
+		// I didn't understood where preemptive switch must occurs
+		k_yield();
+#else
 		IDLE_YIELD_IF_COOP();
+#endif
 	}
 }
diff --git a/kernel/unified/include/kernel_structs.h b/kernel/unified/include/kernel_structs.h
index 8ec5d99..f29402b 100644
--- a/kernel/unified/include/kernel_structs.h
+++ b/kernel/unified/include/kernel_structs.h
@@ -150,6 +150,9 @@ struct _kernel {
 
 	/* nested interrupt count */
 	uint32_t nested;
+#ifdef CONFIG_RISCV64
+	uint32_t dummy_align8;
+#endif
 
 	/* interrupt stack pointer base */
 	char *irq_stack;
diff --git a/kernel/unified/init.c b/kernel/unified/init.c
index 67e12d0..ad64cf3 100644
--- a/kernel/unified/init.c
+++ b/kernel/unified/init.c
@@ -370,7 +370,11 @@ FUNC_NORETURN void _Cstart(void)
 #else
 	/* floating point is NOT used during nanokernel init */
 
+#ifdef CONFIG_RISCV64
+	char __stack dummy_stack[sizeof(struct k_thread)];
+#else
 	char __stack dummy_stack[_K_THREAD_NO_FLOAT_SIZEOF];
+#endif
 	void *dummy_thread = dummy_stack;
 #endif
 
diff --git a/lib/libc/minimal/include/sys/types.h b/lib/libc/minimal/include/sys/types.h
index 25a2fec..60d88ff 100644
--- a/lib/libc/minimal/include/sys/types.h
+++ b/lib/libc/minimal/include/sys/types.h
@@ -28,6 +28,8 @@ typedef int ssize_t;
 typedef int ssize_t;
 #elif defined(__NIOS2__)
 typedef int ssize_t;
+#elif defined(CONFIG_RISCV64)
+typedef long long ssize_t;
 #else
 #error "The minimal libc library does not recognize the architecture!\n"
 #endif
@@ -45,6 +47,8 @@ typedef int off_t;
 typedef int off_t;
 #elif defined(__NIOS2__)
 typedef int off_t;
+#elif defined(CONFIG_RISCV64)
+typedef long long off_t;
 #else
 #error "The minimal libc library does not recognize the architecture!\n"
 #endif
diff --git a/scripts/gen_offset_header/Makefile b/scripts/gen_offset_header/Makefile
index 8e6f3b3..9458eb8 100644
--- a/scripts/gen_offset_header/Makefile
+++ b/scripts/gen_offset_header/Makefile
@@ -1,4 +1,7 @@
 HOSTCFLAGS_gen_offset_header.o += -DKERNEL_VERSION=0 -Wall -Werror -g
+ifeq ($(ARCH),riscv64)
+HOSTCFLAGS_gen_offset_header.o += -DARCH_64BITS
+endif
 HOSTCFLAGS_gen_idt.o += -Wno-unused-result
 
 hostprogs-y	+= gen_offset_header
diff --git a/scripts/gen_offset_header/elf.h b/scripts/gen_offset_header/elf.h
index 449e6ad..da86c85 100644
--- a/scripts/gen_offset_header/elf.h
+++ b/scripts/gen_offset_header/elf.h
@@ -28,9 +28,16 @@
 extern "C" {
 #endif
 
+#ifdef ARCH_64BITS
+#include <inttypes.h>
+typedef uint64_t   Elf32_Addr;
+typedef uint64_t   Elf32_Off;
+typedef uint64_t   Elf32_DWord;
+#else
 typedef unsigned int    Elf32_Addr;
-typedef unsigned short  Elf32_Half;
 typedef unsigned int    Elf32_Off;
+#endif
+typedef unsigned short  Elf32_Half;
 typedef int             Elf32_Sword;
 typedef unsigned int    Elf32_Word;
 
@@ -168,14 +175,26 @@ typedef struct
 	{
 	Elf32_Word	sh_name;
 	Elf32_Word	sh_type;	/* SHT_... */
+#ifdef ARCH_64BITS
+	Elf32_DWord	sh_flags;	/* SHF_... */
+	Elf32_Addr	sh_addr;
+	Elf32_Off	sh_offset;
+	Elf32_DWord	sh_size;
+#else
 	Elf32_Word	sh_flags;	/* SHF_... */
 	Elf32_Addr	sh_addr;
 	Elf32_Off	sh_offset;
 	Elf32_Word	sh_size;
+#endif
 	Elf32_Word	sh_link;
 	Elf32_Word	sh_info;
+#ifdef ARCH_64BITS
+	Elf32_DWord	sh_addralign;
+	Elf32_DWord	sh_entsize;
+#else
 	Elf32_Word	sh_addralign;
 	Elf32_Word	sh_entsize;
+#endif
 } Elf32_Shdr;
 
 #define SHDRSZ sizeof(Elf32_Shdr)
@@ -228,11 +247,19 @@ typedef struct
 typedef struct
 	{
 	Elf32_Word	st_name;
+#ifdef ARCH_64BITS
+	unsigned char	st_info;
+	unsigned char	st_other;
+	Elf32_Half	st_shndx;
+	Elf32_Addr	st_value;
+	Elf32_DWord	st_size;
+#else
 	Elf32_Addr	st_value;
 	Elf32_Word	st_size;
 	unsigned char	st_info;
 	unsigned char	st_other;
 	Elf32_Half	st_shndx;
+#endif
 	} Elf32_Sym;
 
 #define STN_UNDEF	0
@@ -300,10 +327,17 @@ typedef struct
 	Elf32_Off	p_offset;
 	Elf32_Addr	p_vaddr;
 	Elf32_Addr	p_paddr;
+#ifdef ARCH_64BITS
+	Elf32_DWord	p_filesz;
+	Elf32_DWord	p_memsz;
+	Elf32_DWord	p_flags;
+	Elf32_DWord	p_align;
+#else
 	Elf32_Word	p_filesz;
 	Elf32_Word	p_memsz;
 	Elf32_Word	p_flags;
 	Elf32_Word	p_align;
+#endif
 	} Elf32_Phdr;
 
 #define PHDRSZ sizeof(Elf32_Phdr)
diff --git a/scripts/gen_offset_header/gen_offset_header.c b/scripts/gen_offset_header/gen_offset_header.c
index 7f72fed..fd22f25 100644
--- a/scripts/gen_offset_header/gen_offset_header.c
+++ b/scripts/gen_offset_header/gen_offset_header.c
@@ -259,11 +259,19 @@ static int ehdrLoad(int fd)
 
 	/* 64-bit ELF module not supported (for now) */
 
+#ifdef ARCH_64BITS
+	if (ehdr.e_ident[EI_CLASS] != ELFCLASS64)
+	{
+		fprintf(stderr, "ELF32 class not supported\n");
+		return -1;
+	}
+#else
 	if (ehdr.e_ident[EI_CLASS] != ELFCLASS32)
 	{
 		fprintf(stderr, "ELF64 class not supported\n");
 		return -1;
 	}
+#endif
 
 	/*
 	 * Dynamically determine the endianess of the host (in the absence of
@@ -341,7 +349,7 @@ static int shdrsLoad(int fd)
  * @param pSymTblSize ptr to symbol table size
  * @returns 0 if found, -1 if not
  */
-static int symTblFind(unsigned *pSymTblOffset, unsigned *pSymTblSize)
+static int symTblFind(Elf32_Off *pSymTblOffset, unsigned *pSymTblSize)
 {
 	unsigned  ix;    /* loop index */
 
@@ -534,8 +542,13 @@ static void headerAbsoluteSymbolsDump(int fd, FILE *fp, Elf32_Off symTblOffset,
 					(strstr(&pStringTable[aSym.st_name],
 						 STRUCT_SIZ_SUFFIX) != NULL))
 			{
+#ifdef ARCH_64BITS
+				fprintf(fp, "#define\t%s\t0x%" PRIx64 "\n",
+						&pStringTable[aSym.st_name], aSym.st_value);
+#else
 				fprintf(fp, "#define\t%s\t0x%X\n",
 						&pStringTable[aSym.st_name], aSym.st_value);
+#endif
 			}
 		}
 	}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.