diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-20 10:35:35 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-20 13:52:14 +0200 |
commit | 99648958668d3a33ee57974479b36201fe303f34 (patch) | |
tree | 6f27ea790e2823c6156e71219a4f54680263fac6 /bsps/sparc/leon3 | |
parent | fbcd7c8fa65eb695e96a62ea1c1ac7a024fa9dfc (diff) |
bsps: Move startup files to bsps
Adjust build support files to new directory layout.
This patch is a part of the BSP source reorganization.
Update #3285.
Diffstat (limited to 'bsps/sparc/leon3')
-rw-r--r-- | bsps/sparc/leon3/start/bsp_fatal_halt.c | 36 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/bsp_specs | 9 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/bspclean.c | 83 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/bspdelay.c | 27 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/bspidle.S | 28 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/bspsmp.c | 97 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/bspstart.c | 125 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/cpucounter.c | 80 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/eirq.c | 66 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/linkcmds.gr712rc | 22 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/linkcmds.gr740 | 21 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/linkcmds.leon3 | 22 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/linkcmds.ut699 | 22 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/linkcmds.ut700 | 22 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/setvec.c | 64 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/spurious.c | 183 |
16 files changed, 907 insertions, 0 deletions
diff --git a/bsps/sparc/leon3/start/bsp_fatal_halt.c b/bsps/sparc/leon3/start/bsp_fatal_halt.c new file mode 100644 index 0000000000..fa907a3363 --- /dev/null +++ b/bsps/sparc/leon3/start/bsp_fatal_halt.c @@ -0,0 +1,36 @@ +/** + * @file + * @ingroup sparc_leon3 + * @brief LEON3 BSP Fatal_halt handler. + * + * COPYRIGHT (c) 2014. + * Aeroflex Gaisler AB. + * + * 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 <leon.h> + +#ifdef BSP_POWER_DOWN_AT_FATAL_HALT + +/* Power down LEON CPU on fatal error exit */ +void _CPU_Fatal_halt(uint32_t source, uint32_t error) +{ + sparc_disable_interrupts(); + leon3_power_down_loop(); +} + +#else + +/* return to debugger, simulator, hypervisor or similar by exiting + * with an error code. g1=1, g2=FATAL_SOURCE, G3=error-code. + */ +void _CPU_Fatal_halt(uint32_t source, uint32_t error) +{ + sparc_syscall_exit(source, error); +} + +#endif diff --git a/bsps/sparc/leon3/start/bsp_specs b/bsps/sparc/leon3/start/bsp_specs new file mode 100644 index 0000000000..87638cc027 --- /dev/null +++ b/bsps/sparc/leon3/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/sparc/leon3/start/bspclean.c b/bsps/sparc/leon3/start/bspclean.c new file mode 100644 index 0000000000..eff9c8635b --- /dev/null +++ b/bsps/sparc/leon3/start/bspclean.c @@ -0,0 +1,83 @@ +/** + * @file + * @ingroup sparc_leon3 + * @brief LEON3 BSP fatal extension + * + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * COPYRIGHT (c) 2014 + * Aeroflex Gaisler + * + * 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/bootcard.h> +#include <rtems/bspIo.h> +#include <rtems/score/smpimpl.h> + +void bsp_fatal_extension( + rtems_fatal_source source, + bool always_set_to_false, + rtems_fatal_code code +) +{ + /* On SMP we must wait for all other CPUs not requesting a fatal halt, they + * are responding to another CPU's fatal request. These CPUs goes into + * power-down. The CPU requesting fatal halt waits for the others and then + * handles the system shutdown via the normal procedure. + */ + #ifdef RTEMS_SMP + if ((source == RTEMS_FATAL_SOURCE_SMP) && + (code == SMP_FATAL_SHUTDOWN_RESPONSE)) { + leon3_power_down_loop(); /* CPU didn't start shutdown sequence .. */ + } else { + volatile struct irqmp_regs *irqmp = LEON3_IrqCtrl_Regs; + + if (irqmp != NULL) { + /* + * Value was choosen to get something in the magnitude of 1ms on a 200MHz + * processor. + */ + uint32_t max_wait = 1234567; + uint32_t self_cpu = rtems_get_current_processor(); + uint32_t cpu_count = rtems_get_processor_count(); + uint32_t halt_mask = 0; + uint32_t i; + + for (i = 0; i < cpu_count; ++i) { + if ( (i != self_cpu) && _SMP_Should_start_processor( i ) ) { + halt_mask |= UINT32_C(1) << i; + } + } + + /* Wait some time for secondary processors to halt */ + i = 0; + while ((irqmp->mpstat & halt_mask) != halt_mask && i < max_wait) { + ++i; + } + } + } + #endif + + #if (BSP_PRINT_EXCEPTION_CONTEXT) + if ( source == RTEMS_FATAL_SOURCE_EXCEPTION ) { + rtems_exception_frame_print( (const rtems_exception_frame *) code ); + } + #endif + + /* + * If user wants to implement custom reset/reboot it can be done here + */ + #if (BSP_RESET_BOARD_AT_EXIT) + bsp_reset(); + #endif +} diff --git a/bsps/sparc/leon3/start/bspdelay.c b/bsps/sparc/leon3/start/bspdelay.c new file mode 100644 index 0000000000..938a8bdccb --- /dev/null +++ b/bsps/sparc/leon3/start/bspdelay.c @@ -0,0 +1,27 @@ +/** + * @file + * + * LEON3 BSP Delay Method + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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> + +void rtems_bsp_delay(int usecs) +{ + uint32_t then; + + then =LEON3_Timer_Regs->timer[0].value; + then += usecs; + + while (LEON3_Timer_Regs->timer[0].value >= then) + ; +} diff --git a/bsps/sparc/leon3/start/bspidle.S b/bsps/sparc/leon3/start/bspidle.S new file mode 100644 index 0000000000..8557ff42a1 --- /dev/null +++ b/bsps/sparc/leon3/start/bspidle.S @@ -0,0 +1,28 @@ +/* + * Idle Thread Body + * + * This routine puts LEON3 in power-down mode. + * + * COPYRIGHT (c) 2004. + * Gaisler Research. + * + * 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 <rtems/asm.h> + +/* LEON specific power-down function */ + + .align 4 + PUBLIC(bsp_idle_thread) + PUBLIC(leon3_power_down_loop) +SYM(bsp_idle_thread): +SYM(leon3_power_down_loop): +pwdloop: mov %g0, %asr19 + lda [%sp] 1, %g0 ! Needed for UT699 and GR712 + ba,a pwdloop + nop diff --git a/bsps/sparc/leon3/start/bspsmp.c b/bsps/sparc/leon3/start/bspsmp.c new file mode 100644 index 0000000000..280788fa1c --- /dev/null +++ b/bsps/sparc/leon3/start/bspsmp.c @@ -0,0 +1,97 @@ +/** + * @file + * @ingroup sparc_leon3 + * @brief LEON3 SMP BSP Support + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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/bootcard.h> +#include <bsp/fatal.h> +#include <leon.h> +#include <rtems/bspIo.h> +#include <rtems/score/smpimpl.h> +#include <stdlib.h> + +#if !defined(__leon__) || defined(RTEMS_PARAVIRT) +uint32_t _CPU_SMP_Get_current_processor( void ) +{ + return _LEON3_Get_current_processor(); +} +#endif + +static rtems_isr bsp_inter_processor_interrupt( + rtems_vector_number vector +) +{ + _SMP_Inter_processor_interrupt_handler(); +} + +void bsp_start_on_secondary_processor() +{ + uint32_t cpu_index_self = _CPU_SMP_Get_current_processor(); + + /* + * If data cache snooping is not enabled we terminate using BSP_fatal_exit() + * instead of bsp_fatal(). This is done since the latter function tries to + * acquire a ticket lock, an operation which requires data cache snooping to + * be enabled. + */ + if ( !leon3_data_cache_snooping_enabled() ) + BSP_fatal_exit( LEON3_FATAL_INVALID_CACHE_CONFIG_SECONDARY_PROCESSOR ); + + /* Unmask IPI interrupts at Interrupt controller for this CPU */ + LEON3_IrqCtrl_Regs->mask[cpu_index_self] |= 1U << LEON3_mp_irq; + + _SMP_Start_multitasking_on_secondary_processor(); +} + +uint32_t _CPU_SMP_Initialize( void ) +{ + if ( !leon3_data_cache_snooping_enabled() ) + bsp_fatal( LEON3_FATAL_INVALID_CACHE_CONFIG_MAIN_PROCESSOR ); + + if ( rtems_configuration_get_maximum_processors() > 1 ) { + LEON_Unmask_interrupt(LEON3_mp_irq); + set_vector(bsp_inter_processor_interrupt, LEON_TRAP_TYPE(LEON3_mp_irq), 1); + } + + return leon3_get_cpu_count(LEON3_IrqCtrl_Regs); +} + +bool _CPU_SMP_Start_processor( uint32_t cpu_index ) +{ + #if defined(RTEMS_DEBUG) + printk( "Waking CPU %d\n", cpu_index ); + #endif + + LEON3_IrqCtrl_Regs->mpstat = 1U << cpu_index; + + return true; +} + +void _CPU_SMP_Finalize_initialization( uint32_t cpu_count ) +{ + (void) cpu_count; + + /* Nothing to do */ +} + +void _CPU_SMP_Prepare_start_multitasking( void ) +{ + rtems_cache_invalidate_entire_instruction(); +} + +void _CPU_SMP_Send_interrupt(uint32_t target_processor_index) +{ + /* send interrupt to destination CPU */ + LEON3_IrqCtrl_Regs->force[target_processor_index] = 1 << LEON3_mp_irq; +} diff --git a/bsps/sparc/leon3/start/bspstart.c b/bsps/sparc/leon3/start/bspstart.c new file mode 100644 index 0000000000..58fc7d0907 --- /dev/null +++ b/bsps/sparc/leon3/start/bspstart.c @@ -0,0 +1,125 @@ +/* + * This set of routines starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before any of these are invoked. + * + * COPYRIGHT (c) 2011 + * Aeroflex Gaisler + * + * COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * Modified for LEON3 BSP. + * COPYRIGHT (c) 2004. + * Gaisler Research. + * + * 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 <leon.h> +#include <bsp/bootcard.h> +#include <drvmgr/drvmgr.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 LEON3_mp_irq __attribute__((weak)) = 14; +#endif + +/* + * Tells us if data cache snooping is available + */ +int CPU_SPARC_HAS_SNOOPING; + +/* Index of CPU, in an AMP system CPU-index may be non-zero */ +uint32_t LEON3_Cpu_Index = 0; + +#if defined(RTEMS_SMP) +/* Index of the boot CPU. Set by the first CPU at boot to its CPU ID. */ +int LEON3_Boot_Cpu = -1; +#endif + +/* + * set_snooping + * + * Read the cache control register to determine if + * bus snooping is available and enabled. This is needed for some + * drivers so that they can select the most efficient copy routines. + * + */ + +static inline int set_snooping(void) +{ + return (leon3_get_cache_control_register() >> 23) & 1; +} + +/* + * bsp_start + * + * This routine does the bulk of the system initialization. + */ +void bsp_start( void ) +{ + CPU_SPARC_HAS_SNOOPING = set_snooping(); +} + +static void leon3_cpu_index_init(void) +{ + /* Get the LEON3 CPU index, normally 0, but for MP systems we do + * _not_ assume that this is CPU0. One may run another OS on CPU0 + * and RTEMS on this CPU, and AMP system with mixed operating + * systems + */ + LEON3_Cpu_Index = _LEON3_Get_current_processor(); +} + +RTEMS_SYSINIT_ITEM( + leon3_cpu_index_init, + RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_FIRST +); + +static void leon3_interrupt_common_init( void ) +{ + /* Initialize shared interrupt handling, must be done after IRQ + * controller has been found and initialized. + */ + BSP_shared_interrupt_init(); +} + +/* + * Called just before drivers are initialized. Is used to initialize shared + * interrupt handling. + */ +static void leon3_pre_driver_hook( void ) +{ + bsp_spurious_initialize(); + +#ifndef RTEMS_DRVMGR_STARTUP + leon3_interrupt_common_init(); +#endif +} + +RTEMS_SYSINIT_ITEM( + leon3_pre_driver_hook, + RTEMS_SYSINIT_BSP_PRE_DRIVERS, + RTEMS_SYSINIT_ORDER_MIDDLE +); + +#ifdef RTEMS_DRVMGR_STARTUP +/* + * Initialize shared interrupt handling, must be done after IRQ controller has + * been found and initialized. + */ +RTEMS_SYSINIT_ITEM( + leon3_interrupt_common_init, + RTEMS_SYSINIT_DRVMGR_LEVEL_1, + RTEMS_SYSINIT_ORDER_LAST +); +#endif diff --git a/bsps/sparc/leon3/start/cpucounter.c b/bsps/sparc/leon3/start/cpucounter.c new file mode 100644 index 0000000000..87554ce550 --- /dev/null +++ b/bsps/sparc/leon3/start/cpucounter.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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 <leon.h> + +#include <rtems/counter.h> +#include <rtems/sysinit.h> +#include <rtems/score/sparcimpl.h> + +static void leon3_counter_initialize(void) +{ + volatile struct irqmp_timestamp_regs *irqmp_ts; + volatile struct gptimer_regs *gpt; + unsigned int freq; + + irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0]; + gpt = LEON3_Timer_Regs; + + leon3_up_counter_enable(); + + if (leon3_up_counter_is_available()) { + /* Use the LEON4 up-counter if available */ + + _SPARC_Counter_initialize( + _SPARC_Counter_read_asr23, + _SPARC_Counter_difference_normal, + NULL + ); + + freq = leon3_up_counter_frequency(); + rtems_counter_initialize_converter(freq); + } else if (leon3_irqmp_has_timestamp(irqmp_ts)) { + /* Use the interrupt controller timestamp counter if available */ + + /* Enable interrupt timestamping for an arbitrary interrupt line */ + irqmp_ts->control = 0x1; + + _SPARC_Counter_initialize( + _SPARC_Counter_read_address, + _SPARC_Counter_difference_normal, + (volatile const uint32_t *) &irqmp_ts->counter + ); + + freq = ambapp_freq_get(&ambapp_plb, LEON3_IrqCtrl_Adev); + rtems_counter_initialize_converter(freq); + } else if (gpt != NULL) { + /* Fall back to the first GPTIMER if available */ + + /* Enable timer just in case no clock driver is configured */ + gpt->timer[LEON3_CLOCK_INDEX].ctrl |= GPTIMER_TIMER_CTRL_EN; + + _SPARC_Counter_initialize( + _SPARC_Counter_read_address, + _SPARC_Counter_difference_clock_period, + (volatile const uint32_t *) &gpt->timer[LEON3_CLOCK_INDEX].value + ); + + freq = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev); + rtems_counter_initialize_converter(freq / (gpt->scaler_reload - 1)); + } +} + +RTEMS_SYSINIT_ITEM( + leon3_counter_initialize, + RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_THIRD +); + +SPARC_COUNTER_DEFINITION; diff --git a/bsps/sparc/leon3/start/eirq.c b/bsps/sparc/leon3/start/eirq.c new file mode 100644 index 0000000000..1f7be1ba74 --- /dev/null +++ b/bsps/sparc/leon3/start/eirq.c @@ -0,0 +1,66 @@ +/* + * GRLIB/LEON3 extended interrupt controller + * + * COPYRIGHT (c) 2011 + * Aeroflex Gaisler + * + * 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 <leon.h> +#include <bsp/irq.h> + +/* GRLIB extended IRQ controller IRQ number */ +int LEON3_IrqCtrl_EIrq = -1; + +/* Initialize Extended Interrupt controller */ +void leon3_ext_irq_init(void) +{ + if ( (LEON3_IrqCtrl_Regs->mpstat >> 16) & 0xf ) { + /* Extended IRQ controller available */ + LEON3_IrqCtrl_EIrq = (LEON3_IrqCtrl_Regs->mpstat >> 16) & 0xf; + } +} + +void bsp_interrupt_set_affinity( + rtems_vector_number vector, + const Processor_mask *affinity +) +{ + uint32_t unmasked = 0; + uint32_t cpu_count = rtems_get_processor_count(); + uint32_t cpu_index; + + for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { + if (_Processor_mask_Is_set(affinity, cpu_index)) { + BSP_Cpu_Unmask_interrupt(vector, cpu_index); + ++unmasked; + } + } + + if (unmasked > 1) { + LEON_Enable_interrupt_broadcast(vector); + } else { + LEON_Disable_interrupt_broadcast(vector); + } +} + +void bsp_interrupt_get_affinity( + rtems_vector_number vector, + Processor_mask *affinity +) +{ + uint32_t cpu_count = rtems_get_processor_count(); + uint32_t cpu_index; + + _Processor_mask_Zero(affinity); + + for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { + if (!BSP_Cpu_Is_interrupt_masked(vector, cpu_index)) { + _Processor_mask_Set(affinity, cpu_index); + } + } +} diff --git a/bsps/sparc/leon3/start/linkcmds.gr712rc b/bsps/sparc/leon3/start/linkcmds.gr712rc new file mode 100644 index 0000000000..6954e88f45 --- /dev/null +++ b/bsps/sparc/leon3/start/linkcmds.gr712rc @@ -0,0 +1,22 @@ +/* linkcmds + */ + +/* Default values, can be overridden */ + +_PROM_SIZE = DEFINED (_PROM_SIZE) ? _PROM_SIZE : 2M; +_PROM_START = DEFINED (_PROM_START) ? _PROM_START : 0x00000000; + +_RAM_SIZE = DEFINED (_RAM_SIZE) ? _RAM_SIZE : 4M; +_RAM_START = DEFINED (_RAM_START) ? _RAM_START : 0x40000000; + +/* these are the maximum values */ + +MEMORY +{ + rom : ORIGIN = 0x00000000, LENGTH = 256M + ram : ORIGIN = 0x40000000, LENGTH = 1024M +} + +ENTRY(start) + +INCLUDE linkcmds.base diff --git a/bsps/sparc/leon3/start/linkcmds.gr740 b/bsps/sparc/leon3/start/linkcmds.gr740 new file mode 100644 index 0000000000..c16fd7fd7f --- /dev/null +++ b/bsps/sparc/leon3/start/linkcmds.gr740 @@ -0,0 +1,21 @@ +/* Default values, can be overridden */ + +_PROM_SIZE = DEFINED (_PROM_SIZE) ? _PROM_SIZE : 0; + +_RAM_SIZE = DEFINED (_RAM_SIZE) ? _RAM_SIZE : 64M; + +/* these are the maximum values */ + +MEMORY +{ + rom : ORIGIN = 0xC0000000, LENGTH = 256M + ram : ORIGIN = 0x00000000, LENGTH = 2048M + sram : ORIGIN = 0xD0000000, LENGTH = 256M +} + +_PROM_START = ORIGIN (rom); +_RAM_START = ORIGIN (ram); + +ENTRY(start) + +INCLUDE linkcmds.base diff --git a/bsps/sparc/leon3/start/linkcmds.leon3 b/bsps/sparc/leon3/start/linkcmds.leon3 new file mode 100644 index 0000000000..6954e88f45 --- /dev/null +++ b/bsps/sparc/leon3/start/linkcmds.leon3 @@ -0,0 +1,22 @@ +/* linkcmds + */ + +/* Default values, can be overridden */ + +_PROM_SIZE = DEFINED (_PROM_SIZE) ? _PROM_SIZE : 2M; +_PROM_START = DEFINED (_PROM_START) ? _PROM_START : 0x00000000; + +_RAM_SIZE = DEFINED (_RAM_SIZE) ? _RAM_SIZE : 4M; +_RAM_START = DEFINED (_RAM_START) ? _RAM_START : 0x40000000; + +/* these are the maximum values */ + +MEMORY +{ + rom : ORIGIN = 0x00000000, LENGTH = 256M + ram : ORIGIN = 0x40000000, LENGTH = 1024M +} + +ENTRY(start) + +INCLUDE linkcmds.base diff --git a/bsps/sparc/leon3/start/linkcmds.ut699 b/bsps/sparc/leon3/start/linkcmds.ut699 new file mode 100644 index 0000000000..6954e88f45 --- /dev/null +++ b/bsps/sparc/leon3/start/linkcmds.ut699 @@ -0,0 +1,22 @@ +/* linkcmds + */ + +/* Default values, can be overridden */ + +_PROM_SIZE = DEFINED (_PROM_SIZE) ? _PROM_SIZE : 2M; +_PROM_START = DEFINED (_PROM_START) ? _PROM_START : 0x00000000; + +_RAM_SIZE = DEFINED (_RAM_SIZE) ? _RAM_SIZE : 4M; +_RAM_START = DEFINED (_RAM_START) ? _RAM_START : 0x40000000; + +/* these are the maximum values */ + +MEMORY +{ + rom : ORIGIN = 0x00000000, LENGTH = 256M + ram : ORIGIN = 0x40000000, LENGTH = 1024M +} + +ENTRY(start) + +INCLUDE linkcmds.base diff --git a/bsps/sparc/leon3/start/linkcmds.ut700 b/bsps/sparc/leon3/start/linkcmds.ut700 new file mode 100644 index 0000000000..6954e88f45 --- /dev/null +++ b/bsps/sparc/leon3/start/linkcmds.ut700 @@ -0,0 +1,22 @@ +/* linkcmds + */ + +/* Default values, can be overridden */ + +_PROM_SIZE = DEFINED (_PROM_SIZE) ? _PROM_SIZE : 2M; +_PROM_START = DEFINED (_PROM_START) ? _PROM_START : 0x00000000; + +_RAM_SIZE = DEFINED (_RAM_SIZE) ? _RAM_SIZE : 4M; +_RAM_START = DEFINED (_RAM_START) ? _RAM_START : 0x40000000; + +/* these are the maximum values */ + +MEMORY +{ + rom : ORIGIN = 0x00000000, LENGTH = 256M + ram : ORIGIN = 0x40000000, LENGTH = 1024M +} + +ENTRY(start) + +INCLUDE linkcmds.base diff --git a/bsps/sparc/leon3/start/setvec.c b/bsps/sparc/leon3/start/setvec.c new file mode 100644 index 0000000000..5b5888d51a --- /dev/null +++ b/bsps/sparc/leon3/start/setvec.c @@ -0,0 +1,64 @@ +/** + * @file + * @ingroup sparc_leon3 + * @brief Install an interrupt vector on SPARC + */ + +/* This routine installs an interrupt vector on the SPARC simulator. + * + * INPUT PARAMETERS: + * handler - interrupt handler entry point + * vector - vector number + * type - 0 indicates raw hardware connect + * 1 indicates RTEMS interrupt connect + * + * OUTPUT PARAMETERS: NONE + * + * RETURNS: + * address of previous interrupt handler + */ + +/* COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * + * 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. + * + * Ported to LEON implementation of the SPARC by On-Line Applications + * Research Corporation (OAR) under contract to the European Space + * Agency (ESA). + * + * LEON modifications of respective RTEMS file: COPYRIGHT (c) 1995. + * European Space Agency. + */ + +#include <bsp.h> + +rtems_isr_entry set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +) +{ + rtems_isr_entry previous_isr; + uint32_t real_trap; + uint32_t source; + + if ( type ) + rtems_interrupt_catch( handler, vector, &previous_isr ); + else + _CPU_ISR_install_raw_handler( vector, handler, (void *)&previous_isr ); + + real_trap = SPARC_REAL_TRAP_NUMBER( vector ); + + if ( LEON_INT_TRAP( real_trap ) ) { + + source = LEON_TRAP_SOURCE( real_trap ); + + LEON_Clear_interrupt( source ); + LEON_Unmask_interrupt( source ); + } + + return previous_isr; +} diff --git a/bsps/sparc/leon3/start/spurious.c b/bsps/sparc/leon3/start/spurious.c new file mode 100644 index 0000000000..23ac4bf4cf --- /dev/null +++ b/bsps/sparc/leon3/start/spurious.c @@ -0,0 +1,183 @@ +/* + * LEON Spurious Trap Handler + * + * This is just enough of a trap handler to let us know what + * the likely source of the trap was. + * + * Developed as part of the port of RTEMS to the LEON implementation + * of the SPARC by On-Line Applications Research Corporation (OAR) + * under contract to the European Space Agency (ESA). + * + * COPYRIGHT (c) 1995. European Space Agency. + * + * Modified for LEON3 BSP. + * COPYRIGHT (c) 2004. + * Gaisler Research. + * + * This terms of the RTEMS license apply to this file. + */ + +#include <bsp.h> +#include <rtems/score/cpu.h> +#include <rtems/bspIo.h> +#include <inttypes.h> + +void _CPU_Exception_frame_print( const CPU_Exception_frame *frame ) +{ + uint32_t trap; + uint32_t real_trap; + const CPU_Interrupt_frame *isf; + + trap = frame->trap; + real_trap = SPARC_REAL_TRAP_NUMBER(trap); + isf = frame->isf; + + printk( + "Unexpected trap (%2" PRId32 ") at address 0x%08" PRIx32 "\n", + real_trap, + isf->tpc + ); + + switch (real_trap) { + + /* + * First the ones defined by the basic architecture + */ + + case 0x00: + printk( "reset\n" ); + break; + case 0x01: + printk( "instruction access exception\n" ); + break; + case 0x02: + printk( "illegal instruction\n" ); + break; + case 0x03: + printk( "privileged instruction\n" ); + break; + case 0x04: + printk( "fp disabled\n" ); + break; + case 0x07: + printk( "memory address not aligned\n" ); + break; + case 0x08: + printk( "fp exception\n" ); + break; + case 0x0A: + printk( "tag overflow\n" ); + break; + + /* + * Then the ones defined by the LEON in particular + */ + /* FIXME */ + + /* + case LEON_TRAP_TYPE( LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR ): + printk( "LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR\n" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_UART_2_RX_TX ): + printk( "LEON_INTERRUPT_UART_2_RX_TX\n" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_UART_1_RX_TX ): + printk( "LEON_INTERRUPT_UART_1_RX_TX\n" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_0 ): + printk( "LEON_INTERRUPT_EXTERNAL_0\n" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_1 ): + printk( "LEON_INTERRUPT_EXTERNAL_1\n" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_2 ): + printk( "LEON_INTERRUPT_EXTERNAL_2\n" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_3 ): + printk( "LEON_INTERRUPT_EXTERNAL_3\n" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER1 ): + printk( "LEON_INTERRUPT_TIMER1\n" ); + break; + case LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER2 ): + printk( "LEON_INTERRUPT_TIMER2\n" ); + break; + */ + + default: + break; + } +} + +static rtems_isr bsp_spurious_handler( + rtems_vector_number trap, + CPU_Interrupt_frame *isf +) +{ + CPU_Exception_frame frame = { + .trap = trap, + .isf = isf + }; + +#if !defined(SPARC_USE_LAZY_FP_SWITCH) + if ( SPARC_REAL_TRAP_NUMBER( trap ) == 4 ) { + _Internal_error( INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT ); + } +#endif + + rtems_fatal( + RTEMS_FATAL_SOURCE_EXCEPTION, + (rtems_fatal_code) &frame + ); +} + +/* + * bsp_spurious_initialize + * + * Install the spurious handler for most traps. Note that set_vector() + * will unmask the corresponding asynchronous interrupt, so the initial + * interrupt mask is restored after the handlers are installed. + */ + +void bsp_spurious_initialize() +{ + uint32_t trap; + uint32_t level; + /* uint32_t mask; */ + + level = sparc_disable_interrupts(); + /* mask = LEON3_IrqCtrl_Regs->mask_p0; */ + + for ( trap=0 ; trap<256 ; trap++ ) { + + /* + * Skip window overflow, underflow, and flush as well as software + * trap 0,9,10 which we will use as a shutdown, IRQ disable, IRQ enable. + * Also avoid trap 0x70 - 0x7f which cannot happen and where some of the + * space is used to pass parameters to the program. + */ + + if (( trap == 5 ) || ( trap == 6 ) || +#if defined(SPARC_USE_LAZY_FP_SWITCH) + ( trap == 4 ) || +#endif + (( trap >= 0x11 ) && ( trap <= 0x1f )) || + (( trap >= 0x70 ) && ( trap <= 0x83 )) || + ( trap == 0x80 + SPARC_SWTRAP_IRQDIS ) || +#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH) + ( trap == 0x80 + SPARC_SWTRAP_IRQDIS_FP ) || +#endif + ( trap == 0x80 + SPARC_SWTRAP_IRQEN )) + continue; + + set_vector( + (rtems_isr_entry) bsp_spurious_handler, + SPARC_SYNCHRONOUS_TRAP( trap ), + 1 + ); + } + + /* LEON3_IrqCtrl_Regs->mask_p0 = mask; */ + sparc_enable_interrupts(level); + +} |