summaryrefslogtreecommitdiffstats
path: root/bsps/riscv/griscv/start
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/riscv/griscv/start')
-rw-r--r--bsps/riscv/griscv/start/amba.c115
-rw-r--r--bsps/riscv/griscv/start/bsp_fatal_halt.c36
-rw-r--r--bsps/riscv/griscv/start/bsp_specs9
-rw-r--r--bsps/riscv/griscv/start/bspsmp.c97
-rw-r--r--bsps/riscv/griscv/start/bspstart.c70
-rw-r--r--bsps/riscv/griscv/start/linkcmds.in46
6 files changed, 373 insertions, 0 deletions
diff --git a/bsps/riscv/griscv/start/amba.c b/bsps/riscv/griscv/start/amba.c
new file mode 100644
index 0000000000..182f659d69
--- /dev/null
+++ b/bsps/riscv/griscv/start/amba.c
@@ -0,0 +1,115 @@
+
+/*
+ * Find and initialize irqmp and gptimer.
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/fatal.h>
+#include <amba.h>
+
+rtems_interrupt_lock GRLIB_IrqCtrl_Lock =
+ RTEMS_INTERRUPT_LOCK_INITIALIZER("GRLIB IrqCtrl");
+
+/* Pointers to Interrupt Controller configuration registers */
+volatile struct irqmp_regs *GRLIB_IrqCtrl_Regs;
+struct ambapp_dev *GRLIB_IrqCtrl_Adev;
+
+/* GRLIB extended IRQ controller IRQ number */
+int GRLIB_IrqCtrl_EIrq = -1;
+
+/* Initialize Extended Interrupt controller */
+static void grlib_ext_irq_init(void)
+{
+ if ( (GRLIB_IrqCtrl_Regs->mpstat >> 16) & 0xf ) {
+ /* Extended IRQ controller available */
+ GRLIB_IrqCtrl_EIrq = (GRLIB_IrqCtrl_Regs->mpstat >> 16) & 0xf;
+ }
+}
+
+/*
+ * irqmp_initialize
+ *
+ * Probes for IRQMP and initialises necessary registers.
+ *
+ */
+
+void irqmp_initialize(void)
+{
+ int icsel;
+ struct ambapp_dev *adev;
+
+ /* Find GRLIB Interrupt controller */
+ adev = (void *)ambapp_for_each(&ambapp_plb, (OPTIONS_ALL|OPTIONS_APB_SLVS),
+ VENDOR_GAISLER, GAISLER_IRQMP,
+ ambapp_find_by_idx, NULL);
+ if (adev != NULL) {
+
+ GRLIB_IrqCtrl_Regs = (volatile struct irqmp_regs *)DEV_TO_APB(adev)->start;
+ GRLIB_IrqCtrl_Adev = adev;
+ if ((GRLIB_IrqCtrl_Regs->ampctrl >> 28) > 0) {
+ /* IRQ Controller has support for multiple IRQ Controllers, each
+ * CPU can be routed to different Controllers, we find out which
+ * controller by looking at the IRQCTRL Select Register for this CPU.
+ * Each Controller is located at a 4KByte offset.
+ */
+ icsel = GRLIB_IrqCtrl_Regs->icsel[GRLIB_Cpu_Index/8];
+ icsel = (icsel >> ((7 - (GRLIB_Cpu_Index & 0x7)) * 4)) & 0xf;
+ GRLIB_IrqCtrl_Regs += icsel;
+ }
+ GRLIB_IrqCtrl_Regs->mask[GRLIB_Cpu_Index] = 0;
+ GRLIB_IrqCtrl_Regs->force[GRLIB_Cpu_Index] = 0;
+ GRLIB_IrqCtrl_Regs->iclear = 0xffffffff;
+
+ /* Init Extended IRQ controller if available */
+ grlib_ext_irq_init();
+
+ }
+
+}
+
+
+/* GPTIMER */
+
+unsigned int grlib_timer_prescaler __attribute__((weak)) = 0;
+int grlib_timer_core_index __attribute__((weak)) = 0;
+
+volatile struct gptimer_regs *GRLIB_Timer_Regs;
+struct ambapp_dev *GRLIB_Timer_Adev;
+
+/*
+ * gptimer_initialize
+ *
+ */
+
+void gptimer_initialize(void)
+{
+ struct ambapp_dev *adev;
+
+ /* find GP Timer */
+ adev = (void *)ambapp_for_each(&ambapp_plb, (OPTIONS_ALL|OPTIONS_APB_SLVS),
+ VENDOR_GAISLER, GAISLER_GPTIMER,
+ ambapp_find_by_idx, &grlib_timer_core_index);
+ if (adev) {
+ GRLIB_Timer_Regs = (volatile struct gptimer_regs *)DEV_TO_APB(adev)->start;
+ GRLIB_Timer_Adev = adev;
+
+ /* Register AMBA Bus Frequency */
+ ambapp_freq_init(
+ &ambapp_plb,
+ GRLIB_Timer_Adev,
+ (GRLIB_Timer_Regs->scaler_reload + 1)
+ * GRLIB_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER
+ );
+ /* Set user prescaler configuration. Use this to increase accuracy of timer
+ * and accociated services like cpucounter.
+ * Note that minimum value is the number of timer instances present in
+ * GRTIMER/GPTIMER hardware. See HW manual.
+ */
+ if (grlib_timer_prescaler)
+ GRLIB_Timer_Regs->scaler_reload = grlib_timer_prescaler;
+ }
+
+}
diff --git a/bsps/riscv/griscv/start/bsp_fatal_halt.c b/bsps/riscv/griscv/start/bsp_fatal_halt.c
new file mode 100644
index 0000000000..ced328ea0f
--- /dev/null
+++ b/bsps/riscv/griscv/start/bsp_fatal_halt.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH
+ *
+ * Copyright (c) 2015 University of York.
+ * Hesham Almatary <hesham@alumni.york.ac.uk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <bsp.h>
+
+void _CPU_Fatal_halt(uint32_t source, uint32_t error)
+{
+ /* ecall is currently used to halt the griscv cpu */
+ asm ("ecall");
+ for(;;);
+}
diff --git a/bsps/riscv/griscv/start/bsp_specs b/bsps/riscv/griscv/start/bsp_specs
new file mode 100644
index 0000000000..87638cc027
--- /dev/null
+++ b/bsps/riscv/griscv/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/riscv/griscv/start/bspsmp.c b/bsps/riscv/griscv/start/bspsmp.c
new file mode 100644
index 0000000000..df826f8217
--- /dev/null
+++ b/bsps/riscv/griscv/start/bspsmp.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <bsp/bootcard.h>
+#include <bsp/irq.h>
+#include <amba.h>
+
+#include <rtems/score/riscv-utility.h>
+#include <rtems/score/smpimpl.h>
+
+static rtems_isr bsp_inter_processor_interrupt( void *v )
+{
+ _SMP_Inter_processor_interrupt_handler(_Per_CPU_Get());
+}
+
+void bsp_start_on_secondary_processor(Per_CPU_Control *cpu_self)
+{
+ uint32_t cpu_index_self;
+
+ cpu_index_self = _Per_CPU_Get_index(cpu_self);
+ GRLIB_IrqCtrl_Regs->mask[cpu_index_self] |= 1U << GRLIB_mp_irq;
+
+ if (
+ cpu_index_self < rtems_configuration_get_maximum_processors()
+ && _SMP_Should_start_processor(cpu_index_self)
+ ) {
+ set_csr(mie, MIP_MEIP);
+ _SMP_Start_multitasking_on_secondary_processor(cpu_self);
+ } else {
+ _CPU_Thread_Idle_body(0);
+ }
+}
+
+uint32_t _CPU_SMP_Initialize(void)
+{
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ GRLIB_Cpu_Unmask_interrupt(GRLIB_mp_irq, _CPU_SMP_Get_current_processor());
+
+ rtems_interrupt_handler_install(
+ GRLIB_mp_irq,
+ "IPI",
+ RTEMS_INTERRUPT_SHARED,
+ bsp_inter_processor_interrupt,
+ NULL
+ );
+
+ }
+
+ return grlib_get_cpu_count(GRLIB_IrqCtrl_Regs);
+}
+
+bool _CPU_SMP_Start_processor(uint32_t cpu_index)
+{
+ GRLIB_IrqCtrl_Regs->mpstat = 1U << cpu_index;
+
+ return true;
+}
+
+void _CPU_SMP_Finalize_initialization(uint32_t cpu_count)
+{
+ (void) cpu_count;
+// set_csr(mie, MIP_MSIP);
+}
+
+void _CPU_SMP_Prepare_start_multitasking(void)
+{
+ /* Do nothing */
+}
+
+void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
+{
+
+ GRLIB_IrqCtrl_Regs->force[target_processor_index] = 1 << GRLIB_mp_irq;
+
+}
diff --git a/bsps/riscv/griscv/start/bspstart.c b/bsps/riscv/griscv/start/bspstart.c
new file mode 100644
index 0000000000..dd83c80818
--- /dev/null
+++ b/bsps/riscv/griscv/start/bspstart.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <bsp/bootcard.h>
+#include <bsp/fatal.h>
+#include <bsp/irq-generic.h>
+
+#include <amba.h>
+#include <rtems/sysinit.h>
+
+#if defined(RTEMS_SMP) || defined(RTEMS_MULTIPROCESSING)
+/* Irq used by shared memory driver and for inter-processor interrupts.
+ * Can be overridden by being defined in the application.
+ */
+const unsigned char GRLIB_mp_irq __attribute__((weak)) = 14;
+#endif
+
+uint32_t GRLIB_Cpu_Index = 0;
+
+#ifdef RTEMS_SMP
+uint32_t riscv_hart_count = 1;
+/* Index of the boot CPU. Set by the first CPU at boot to its CPU ID. */
+int GRLIB_Boot_Cpu = -1;
+#endif
+
+void bsp_start(void)
+{
+ bsp_interrupt_initialize();
+#ifdef RTEMS_SMP
+ GRLIB_Cpu_Index = _CPU_SMP_Get_current_processor();
+#endif
+}
+
+void amba_initialize(void);
+struct ambapp_bus ambapp_plb;
+
+void amba_initialize(void)
+{
+ ambapp_scan(&ambapp_plb, GRLIB_IO_AREA, NULL, NULL);
+ gptimer_initialize();
+ irqmp_initialize();
+}
+
+RTEMS_SYSINIT_ITEM(
+ amba_initialize,
+ RTEMS_SYSINIT_BSP_START,
+ RTEMS_SYSINIT_ORDER_FIRST
+);
diff --git a/bsps/riscv/griscv/start/linkcmds.in b/bsps/riscv/griscv/start/linkcmds.in
new file mode 100644
index 0000000000..80e2f5ef90
--- /dev/null
+++ b/bsps/riscv/griscv/start/linkcmds.in
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 University of York.
+ * Hesham ALMatary <hmka501@york.ac.uk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+MEMORY
+{
+ RAM : ORIGIN = @RISCV_RAM_REGION_BEGIN@, LENGTH = @RISCV_RAM_REGION_SIZE@
+}
+
+REGION_ALIAS ("REGION_START", RAM);
+REGION_ALIAS ("REGION_TEXT", RAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM);
+REGION_ALIAS ("REGION_RODATA", RAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_RTEMSSTACK", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+
+INCLUDE linkcmds.base