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
}
}
}
