summaryrefslogtreecommitdiffstats
path: root/bsps/sparc/leon3/include
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/sparc/leon3/include')
-rw-r--r--bsps/sparc/leon3/include/amba.h48
-rw-r--r--bsps/sparc/leon3/include/bsp.h250
-rw-r--r--bsps/sparc/leon3/include/bsp/irq.h55
-rw-r--r--bsps/sparc/leon3/include/bsp/watchdog.h49
-rw-r--r--bsps/sparc/leon3/include/leon.h511
-rw-r--r--bsps/sparc/leon3/include/tm27.h84
6 files changed, 997 insertions, 0 deletions
diff --git a/bsps/sparc/leon3/include/amba.h b/bsps/sparc/leon3/include/amba.h
new file mode 100644
index 0000000000..059b28ca07
--- /dev/null
+++ b/bsps/sparc/leon3/include/amba.h
@@ -0,0 +1,48 @@
+/**
+ * @file
+ * @defgroup amba AMBA Driver Handler
+ * @ingroup sparc_leon3
+ * @brief AMBA Plag & Play Bus Driver Macros
+ */
+
+/*
+ * AMBA Plag & Play Bus Driver Macros
+ *
+ * Macros used for AMBA Plug & Play bus scanning
+ *
+ * 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.
+ */
+
+#ifndef __AMBA_H__
+#define __AMBA_H__
+
+#define LEON3_IO_AREA 0xfff00000
+#define LEON3_CONF_AREA 0xff000
+#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11)
+
+#define LEON3_AHB_CONF_WORDS 8
+#define LEON3_APB_CONF_WORDS 2
+#define LEON3_AHB_MASTERS 64
+#define LEON3_AHB_SLAVES 64
+#define LEON3_APB_SLAVES 16
+
+#include <ambapp.h>
+#include <grlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The AMBA Plug&Play info of the bus that the LEON3 sits on */
+extern struct ambapp_bus ambapp_plb;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMBA_H__ */
diff --git a/bsps/sparc/leon3/include/bsp.h b/bsps/sparc/leon3/include/bsp.h
new file mode 100644
index 0000000000..3fda4edc66
--- /dev/null
+++ b/bsps/sparc/leon3/include/bsp.h
@@ -0,0 +1,250 @@
+/**
+ * @file
+ *
+ * @ingroup sparc_leon3
+ *
+ * @brief Global BSP Definitions.
+ */
+
+/* bsp.h
+ *
+ * This include file contains all SPARC simulator definitions.
+ *
+ * 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 ERC32 implementation of the SPARC by On-Line Applications
+ * Research Corporation (OAR) under contract to the European Space
+ * Agency (ESA).
+ *
+ * ERC32 modifications of respective RTEMS file: COPYRIGHT (c) 1995.
+ * European Space Agency.
+ */
+
+#ifndef LIBBSP_SPARC_LEON3_BSP_H
+#define LIBBSP_SPARC_LEON3_BSP_H
+
+#include <bspopts.h>
+#include <bsp/default-initial-extension.h>
+
+#include <rtems.h>
+#include <leon.h>
+#include <rtems/irq-extension.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup sparc_leon3 LEON3 Support
+ *
+ * @ingroup bsp_sparc
+ *
+ * @brief LEON3 support package
+ *
+ */
+
+/* SPARC CPU variant: LEON3 */
+#define LEON3 1
+
+/*
+ * BSP provides its own Idle thread body
+ */
+void *bsp_idle_thread( uintptr_t ignored );
+#define BSP_IDLE_TASK_BODY bsp_idle_thread
+
+/* Maximum supported APBUARTs by BSP */
+#define BSP_NUMBER_OF_TERMIOS_PORTS 8
+
+/* Make sure maximum number of consoles fit in filesystem */
+#define BSP_MAXIMUM_DEVICES 8
+
+/*
+ * Network driver configuration
+ */
+struct rtems_bsdnet_ifconfig;
+extern int rtems_leon_open_eth_driver_attach(
+ struct rtems_bsdnet_ifconfig *config,
+ int attach
+);
+extern int rtems_smc91111_driver_attach_leon3(
+ struct rtems_bsdnet_ifconfig *config,
+ int attach
+);
+extern int rtems_leon_greth_driver_attach(
+ struct rtems_bsdnet_ifconfig *config,
+ int attach
+);
+
+#define RTEMS_BSP_NETWORK_DRIVER_NAME_OPENETH "open_eth1"
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_OPENETH \
+ rtems_leon_open_eth_driver_attach
+#define RTEMS_BSP_NETWORK_DRIVER_NAME_SMC91111 "smc_eth1"
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_SMC91111 \
+ rtems_smc91111_driver_attach_leon3
+#define RTEMS_BSP_NETWORK_DRIVER_NAME_GRETH "gr_eth1"
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_GRETH \
+ rtems_leon_greth_driver_attach
+
+#ifndef RTEMS_BSP_NETWORK_DRIVER_NAME
+#define RTEMS_BSP_NETWORK_DRIVER_NAME RTEMS_BSP_NETWORK_DRIVER_NAME_GRETH
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH RTEMS_BSP_NETWORK_DRIVER_ATTACH_GRETH
+#endif
+
+#define HAS_SMC91111
+
+/* Configure GRETH driver */
+#define GRETH_SUPPORTED
+#define GRETH_MEM_LOAD(addr) leon_r32_no_cache((uintptr_t)addr)
+
+extern int CPU_SPARC_HAS_SNOOPING;
+
+/* Constants */
+
+/*
+ * Information placed in the linkcmds file.
+ */
+
+extern int RAM_START;
+extern int RAM_END;
+extern int RAM_SIZE;
+
+extern int PROM_START;
+extern int PROM_END;
+extern int PROM_SIZE;
+
+extern int CLOCK_SPEED;
+
+extern int end; /* last address in the program */
+
+/* miscellaneous stuff assumed to exist */
+
+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 */
+);
+
+void BSP_fatal_exit(uint32_t error);
+
+void bsp_spurious_initialize( void );
+
+/*
+ * Delay for the specified number of microseconds.
+ */
+void rtems_bsp_delay(int usecs);
+
+/* Interrupt Service Routine (ISR) pointer */
+typedef void (*bsp_shared_isr)(void *arg);
+
+/* Initializes the Shared System Interrupt service */
+extern void BSP_shared_interrupt_init(void);
+
+/* Called directly from IRQ trap handler TRAP[0x10..0x1F] = IRQ[0..15] */
+void bsp_isr_handler(rtems_vector_number vector);
+
+/* Registers a shared IRQ handler, and enable it at IRQ controller. Multiple
+ * interrupt handlers may use the same IRQ number, all ISRs will be called
+ * when an interrupt on that line is fired.
+ *
+ * Arguments
+ * irq System IRQ number
+ * info Optional Name of IRQ source
+ * isr Function pointer to the ISR
+ * arg Second argument to function isr
+ */
+static __inline__ int BSP_shared_interrupt_register
+ (
+ int irq,
+ const char *info,
+ bsp_shared_isr isr,
+ void *arg
+ )
+{
+ return rtems_interrupt_handler_install(irq, info,
+ RTEMS_INTERRUPT_SHARED, isr, arg);
+}
+
+/* Unregister previously registered shared IRQ handler.
+ *
+ * Arguments
+ * irq System IRQ number
+ * isr Function pointer to the ISR
+ * arg Second argument to function isr
+ */
+static __inline__ int BSP_shared_interrupt_unregister
+ (
+ int irq,
+ bsp_shared_isr isr,
+ void *arg
+ )
+{
+ return rtems_interrupt_handler_remove(irq, isr, arg);
+}
+
+/* Clear interrupt pending on IRQ controller, this is typically done on a
+ * level triggered interrupt source such as PCI to avoid taking double IRQs.
+ * In such a case the interrupt source must be cleared first on LEON, before
+ * acknowledging the IRQ with this function.
+ *
+ * Arguments
+ * irq System IRQ number
+ */
+extern void BSP_shared_interrupt_clear(int irq);
+
+/* Enable Interrupt. This function will unmask the IRQ at the interrupt
+ * controller. This is normally done by _register(). Note that this will
+ * affect all ISRs on this IRQ.
+ *
+ * Arguments
+ * irq System IRQ number
+ */
+extern void BSP_shared_interrupt_unmask(int irq);
+
+/* Disable Interrupt. This function will mask one IRQ at the interrupt
+ * controller. This is normally done by _unregister(). Note that this will
+ * affect all ISRs on this IRQ.
+ *
+ * Arguments
+ * irq System IRQ number
+ */
+extern void BSP_shared_interrupt_mask(int irq);
+
+#if defined(RTEMS_SMP) || defined(RTEMS_MULTIPROCESSING)
+/* Irq used by the shared memory driver and for inter-processor interrupts.
+ * The variable is weakly linked. Redefine the variable in your application
+ * to override the BSP default.
+ */
+extern const unsigned char LEON3_mp_irq;
+#endif
+
+#ifdef RTEMS_SMP
+/* Weak table used to implement static interrupt CPU affinity in a SMP
+ * configuration. The array index is the interrupt to be looked up, and
+ * the array[INTERRUPT] content is the CPU number relative to boot CPU
+ * index that will be servicing the interrupts from the IRQ source. The
+ * default is to let the first CPU (the boot cpu) to handle all
+ * interrupts (all zeros).
+ */
+extern const unsigned char LEON3_irq_to_cpu[32];
+#endif
+
+/* Common driver build-time configurations. On small systems undefine
+ * [DRIVER]_INFO_AVAIL to avoid info routines get dragged in. It is good
+ * for debugging and printing information about the system, but makes the
+ * image bigger.
+ */
+#define AMBAPPBUS_INFO_AVAIL /* AMBAPP Bus driver */
+#define APBUART_INFO_AVAIL /* APBUART Console driver */
+#define GPTIMER_INFO_AVAIL /* GPTIMER Timer driver */
+#define GRETH_INFO_AVAIL /* GRETH Ethernet driver */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsps/sparc/leon3/include/bsp/irq.h b/bsps/sparc/leon3/include/bsp/irq.h
new file mode 100644
index 0000000000..c3e7959139
--- /dev/null
+++ b/bsps/sparc/leon3/include/bsp/irq.h
@@ -0,0 +1,55 @@
+/**
+ * @file
+ * @ingroup sparc_leon3
+ * @brief LEON3 generic shared IRQ setup
+ *
+ * Based on libbsp/shared/include/irq.h.
+ */
+
+/*
+ * Copyright (c) 2012.
+ * 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.
+ */
+
+#ifndef LIBBSP_LEON3_IRQ_CONFIG_H
+#define LIBBSP_LEON3_IRQ_CONFIG_H
+
+#include <leon.h>
+#include <rtems/score/processormask.h>
+
+#define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */
+#define BSP_INTERRUPT_VECTOR_MAX_EXT 31 /* Extended IRQ controller */
+
+#define BSP_INTERRUPT_VECTOR_MIN 0
+#define BSP_INTERRUPT_VECTOR_MAX BSP_INTERRUPT_VECTOR_MAX_EXT
+
+/* The check is different depending on IRQ controller, runtime detected */
+#define BSP_INTERRUPT_CUSTOM_VALID_VECTOR
+
+/**
+ * @brief Returns true if the interrupt vector with number @a vector is valid.
+ */
+static inline bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
+{
+ return (rtems_vector_number) BSP_INTERRUPT_VECTOR_MIN <= vector
+ && ((vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX_STD &&
+ LEON3_IrqCtrl_EIrq == 0) ||
+ (vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX_EXT &&
+ LEON3_IrqCtrl_EIrq != 0));
+}
+
+void bsp_interrupt_set_affinity(
+ rtems_vector_number vector,
+ const Processor_mask *affinity
+);
+
+void bsp_interrupt_get_affinity(
+ rtems_vector_number vector,
+ Processor_mask *affinity
+);
+
+#endif /* LIBBSP_LEON3_IRQ_CONFIG_H */
diff --git a/bsps/sparc/leon3/include/bsp/watchdog.h b/bsps/sparc/leon3/include/bsp/watchdog.h
new file mode 100644
index 0000000000..3c63be2a8f
--- /dev/null
+++ b/bsps/sparc/leon3/include/bsp/watchdog.h
@@ -0,0 +1,49 @@
+/* watchdog.h
+ *
+ * The LEON3 BSP timer watch-dog interface
+ *
+ * COPYRIGHT (c) 2012.
+ * Cobham 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.
+ */
+
+#ifndef __WATCHDOG_H__
+#define __WATCHDOG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Initialize BSP watchdog routines. Returns number of watchdog timers found.
+ * Currently only one is supported.
+ */
+int bsp_watchdog_init(void);
+
+/* Reload watchdog (last timer on the first GPTIMER core), all systems does not
+ * feature a watchdog, it is expected that if this function is called the
+ * user knows that there is a watchdog available.
+ *
+ * The prescaler is normally set to number of MHz of system, this is to
+ * make the system clock tick be stable.
+ *
+ * Arguments
+ * watchdog - Always 0 for now
+ * reload_value - Number of timer clocks (after prescaler) to count before
+ * watchdog is woken.
+ */
+void bsp_watchdog_reload(int watchdog, unsigned int reload_value);
+
+/* Stop watchdog timer */
+void bsp_watchdog_stop(int watchdog);
+
+/* Use watchdog0 timer to reset the system */
+void bsp_watchdog_system_reset(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsps/sparc/leon3/include/leon.h b/bsps/sparc/leon3/include/leon.h
new file mode 100644
index 0000000000..758b760b0b
--- /dev/null
+++ b/bsps/sparc/leon3/include/leon.h
@@ -0,0 +1,511 @@
+/**
+ * @file
+ * @ingroup sparc_leon3
+ * @brief LEON3 BSP data types and macros
+ */
+
+/* leon.h
+ *
+ * LEON3 BSP data types and macros.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * 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.
+ */
+
+#ifndef _INCLUDE_LEON_h
+#define _INCLUDE_LEON_h
+
+#include <rtems.h>
+#include <amba.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LEON_INTERRUPT_EXTERNAL_1 5
+
+#ifndef ASM
+/*
+ * Trap Types for on-chip peripherals
+ *
+ * Source: Table 8 - Interrupt Trap Type and Default Priority Assignments
+ *
+ * NOTE: The priority level for each source corresponds to the least
+ * significant nibble of the trap type.
+ */
+
+#define LEON_TRAP_TYPE( _source ) SPARC_ASYNCHRONOUS_TRAP((_source) + 0x10)
+
+#define LEON_TRAP_SOURCE( _trap ) ((_trap) - 0x10)
+
+#define LEON_INT_TRAP( _trap ) \
+ ( (_trap) >= 0x11 && \
+ (_trap) <= 0x1F )
+
+/* /\* */
+/* * This is used to manipulate the on-chip registers. */
+/* * */
+/* * The following symbol must be defined in the linkcmds file and point */
+/* * to the correct location. */
+/* *\/ */
+/* Leon uses dynamic register mapping using amba configuration records */
+/* LEON_Register_Map is obsolete */
+/* extern LEON_Register_Map LEON_REG; */
+
+#endif
+
+/*
+ * The following defines the bits in Memory Configuration Register 1.
+ */
+
+#define LEON_MEMORY_CONFIGURATION_PROM_SIZE_MASK 0x0003C000
+
+/*
+ * The following defines the bits in Memory Configuration Register 1.
+ */
+
+#define LEON_MEMORY_CONFIGURATION_RAM_SIZE_MASK 0x00001E00
+
+
+/*
+ * The following defines the bits in the Timer Control Register.
+ */
+
+#define LEON_REG_TIMER_CONTROL_EN 0x00000001 /* 1 = enable counting */
+ /* 0 = hold scalar and counter */
+#define LEON_REG_TIMER_CONTROL_RL 0x00000002 /* 1 = reload at 0 */
+ /* 0 = stop at 0 */
+#define LEON_REG_TIMER_CONTROL_LD 0x00000004 /* 1 = load counter */
+ /* 0 = no function */
+
+/*
+ * The following defines the bits in the UART Control Registers.
+ */
+
+#define LEON_REG_UART_CONTROL_RTD 0x000000FF /* RX/TX data */
+
+/*
+ * The following defines the bits in the LEON UART Status Register.
+ */
+
+#define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */
+#define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */
+#define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */
+#define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */
+#define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */
+#define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */
+#define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */
+#define LEON_REG_UART_STATUS_TF 0x00000200 /* FIFO Full */
+#define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */
+
+/*
+ * The following defines the bits in the LEON UART Control Register.
+ */
+
+#define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */
+#define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */
+#define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */
+#define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */
+#define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */
+#define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */
+#define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */
+#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */
+#define LEON_REG_UART_CTRL_DB 0x00000800 /* Debug FIFO enable */
+#define LEON_REG_UART_CTRL_SI 0x00004000 /* TX shift register empty IRQ enable */
+#define LEON_REG_UART_CTRL_FA 0x80000000 /* FIFO Available */
+#define LEON_REG_UART_CTRL_FA_BIT 31
+
+/*
+ * The following defines the bits in the LEON Cache Control Register.
+ */
+#define LEON3_REG_CACHE_CTRL_FI 0x00200000 /* Flush instruction cache */
+#define LEON3_REG_CACHE_CTRL_DS 0x00800000 /* Data cache snooping */
+
+/* LEON3 Interrupt Controller */
+extern volatile struct irqmp_regs *LEON3_IrqCtrl_Regs;
+extern struct ambapp_dev *LEON3_IrqCtrl_Adev;
+
+/* LEON3 GP Timer */
+extern volatile struct gptimer_regs *LEON3_Timer_Regs;
+extern struct ambapp_dev *LEON3_Timer_Adev;
+
+/* LEON3 CPU Index of boot CPU */
+extern uint32_t LEON3_Cpu_Index;
+
+/* The external IRQ number, -1 if not external interrupts */
+extern int LEON3_IrqCtrl_EIrq;
+
+static __inline__ int bsp_irq_fixup(int irq)
+{
+ int eirq, cpu;
+
+ if (LEON3_IrqCtrl_EIrq != 0 && irq == LEON3_IrqCtrl_EIrq) {
+ /* Get interrupt number from IRQ controller */
+ cpu = _LEON3_Get_current_processor();
+ eirq = LEON3_IrqCtrl_Regs->intid[cpu] & 0x1f;
+ if (eirq & 0x10)
+ irq = eirq;
+ }
+
+ return irq;
+}
+
+/* Macros used for manipulating bits in LEON3 GP Timer Control Register */
+
+#define LEON3_IRQMPSTATUS_CPUNR 28
+#define LEON3_IRQMPSTATUS_BROADCAST 27
+
+
+#ifndef ASM
+
+/*
+ * Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
+ * and the Interrupt Pending Registers.
+ *
+ * NOTE: For operations which are not atomic, this code disables interrupts
+ * to guarantee there are no intervening accesses to the same register.
+ * The operations which read the register, modify the value and then
+ * store the result back are vulnerable.
+ */
+
+extern rtems_interrupt_lock LEON3_IrqCtrl_Lock;
+
+#define LEON3_IRQCTRL_ACQUIRE( _lock_context ) \
+ rtems_interrupt_lock_acquire( &LEON3_IrqCtrl_Lock, _lock_context )
+
+#define LEON3_IRQCTRL_RELEASE( _lock_context ) \
+ rtems_interrupt_lock_release( &LEON3_IrqCtrl_Lock, _lock_context )
+
+#define LEON_Clear_interrupt( _source ) \
+ do { \
+ LEON3_IrqCtrl_Regs->iclear = (1U << (_source)); \
+ } while (0)
+
+#define LEON_Force_interrupt( _source ) \
+ do { \
+ LEON3_IrqCtrl_Regs->iforce = (1U << (_source)); \
+ } while (0)
+
+#define LEON_Enable_interrupt_broadcast( _source ) \
+ do { \
+ rtems_interrupt_lock_context _lock_context; \
+ uint32_t _mask = 1U << ( _source ); \
+ LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
+ LEON3_IrqCtrl_Regs->bcast |= _mask; \
+ LEON3_IRQCTRL_RELEASE( &_lock_context ); \
+ } while (0)
+
+#define LEON_Disable_interrupt_broadcast( _source ) \
+ do { \
+ rtems_interrupt_lock_context _lock_context; \
+ uint32_t _mask = 1U << ( _source ); \
+ LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
+ LEON3_IrqCtrl_Regs->bcast &= ~_mask; \
+ LEON3_IRQCTRL_RELEASE( &_lock_context ); \
+ } while (0)
+
+#define LEON_Is_interrupt_pending( _source ) \
+ (LEON3_IrqCtrl_Regs->ipend & (1U << (_source)))
+
+#define LEON_Cpu_Is_interrupt_masked( _source, _cpu ) \
+ (!(LEON3_IrqCtrl_Regs->mask[_cpu] & (1U << (_source))))
+
+#define LEON_Cpu_Mask_interrupt( _source, _cpu ) \
+ do { \
+ rtems_interrupt_lock_context _lock_context; \
+ LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
+ LEON3_IrqCtrl_Regs->mask[_cpu] &= ~(1U << (_source)); \
+ LEON3_IRQCTRL_RELEASE( &_lock_context ); \
+ } while (0)
+
+#define LEON_Cpu_Unmask_interrupt( _source, _cpu ) \
+ do { \
+ rtems_interrupt_lock_context _lock_context; \
+ LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
+ LEON3_IrqCtrl_Regs->mask[_cpu] |= (1U << (_source)); \
+ LEON3_IRQCTRL_RELEASE( &_lock_context ); \
+ } while (0)
+
+#define LEON_Cpu_Disable_interrupt( _source, _previous, _cpu ) \
+ do { \
+ rtems_interrupt_lock_context _lock_context; \
+ uint32_t _mask = 1U << (_source); \
+ LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
+ (_previous) = LEON3_IrqCtrl_Regs->mask[_cpu]; \
+ LEON3_IrqCtrl_Regs->mask[_cpu] = _previous & ~_mask; \
+ LEON3_IRQCTRL_RELEASE( &_lock_context ); \
+ (_previous) &= _mask; \
+ } while (0)
+
+#define LEON_Cpu_Restore_interrupt( _source, _previous, _cpu ) \
+ do { \
+ rtems_interrupt_lock_context _lock_context; \
+ uint32_t _mask = 1U << (_source); \
+ LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
+ LEON3_IrqCtrl_Regs->mask[_cpu] = \
+ (LEON3_IrqCtrl_Regs->mask[_cpu] & ~_mask) | (_previous); \
+ LEON3_IRQCTRL_RELEASE( &_lock_context ); \
+ } while (0)
+
+/* Map single-cpu operations to local CPU */
+#define LEON_Is_interrupt_masked( _source ) \
+ LEON_Cpu_Is_interrupt_masked(_source, _LEON3_Get_current_processor())
+
+#define LEON_Mask_interrupt(_source) \
+ LEON_Cpu_Mask_interrupt(_source, _LEON3_Get_current_processor())
+
+#define LEON_Unmask_interrupt(_source) \
+ LEON_Cpu_Unmask_interrupt(_source, _LEON3_Get_current_processor())
+
+#define LEON_Disable_interrupt(_source, _previous) \
+ LEON_Cpu_Disable_interrupt(_source, _previous, _LEON3_Get_current_processor())
+
+#define LEON_Restore_interrupt(_source, _previous) \
+ LEON_Cpu_Restore_interrupt(_source, _previous, _LEON3_Get_current_processor())
+
+/* Make all SPARC BSPs have common macros for interrupt handling */
+#define BSP_Clear_interrupt(_source) LEON_Clear_interrupt(_source)
+#define BSP_Force_interrupt(_source) LEON_Force_interrupt(_source)
+#define BSP_Is_interrupt_pending(_source) LEON_Is_interrupt_pending(_source)
+#define BSP_Is_interrupt_masked(_source) LEON_Is_interrupt_masked(_source)
+#define BSP_Unmask_interrupt(_source) LEON_Unmask_interrupt(_source)
+#define BSP_Mask_interrupt(_source) LEON_Mask_interrupt(_source)
+#define BSP_Disable_interrupt(_source, _previous) \
+ LEON_Disable_interrupt(_source, _prev)
+#define BSP_Restore_interrupt(_source, _previous) \
+ LEON_Restore_interrupt(_source, _previous)
+
+/* Make all SPARC BSPs have common macros for interrupt handling on any CPU */
+#define BSP_Cpu_Is_interrupt_masked(_source, _cpu) \
+ LEON_Cpu_Is_interrupt_masked(_source, _cpu)
+#define BSP_Cpu_Unmask_interrupt(_source, _cpu) \
+ LEON_Cpu_Unmask_interrupt(_source, _cpu)
+#define BSP_Cpu_Mask_interrupt(_source, _cpu) \
+ LEON_Cpu_Mask_interrupt(_source, _cpu)
+#define BSP_Cpu_Disable_interrupt(_source, _previous, _cpu) \
+ LEON_Cpu_Disable_interrupt(_source, _prev, _cpu)
+#define BSP_Cpu_Restore_interrupt(_source, _previous, _cpu) \
+ LEON_Cpu_Restore_interrupt(_source, _previous, _cpu)
+
+/*
+ * Each timer control register is organized as follows:
+ *
+ * D0 - Enable
+ * 1 = enable counting
+ * 0 = hold scaler and counter
+ *
+ * D1 - Counter Reload
+ * 1 = reload counter at zero and restart
+ * 0 = stop counter at zero
+ *
+ * D2 - Counter Load
+ * 1 = load counter with preset value
+ * 0 = no function
+ *
+ */
+
+#define LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO 0x00000002
+#define LEON_REG_TIMER_COUNTER_STOP_AT_ZERO 0x00000000
+
+#define LEON_REG_TIMER_COUNTER_LOAD_COUNTER 0x00000004
+
+#define LEON_REG_TIMER_COUNTER_ENABLE_COUNTING 0x00000001
+#define LEON_REG_TIMER_COUNTER_DISABLE_COUNTING 0x00000000
+
+#define LEON_REG_TIMER_COUNTER_RELOAD_MASK 0x00000002
+#define LEON_REG_TIMER_COUNTER_ENABLE_MASK 0x00000001
+
+#define LEON_REG_TIMER_COUNTER_DEFINED_MASK 0x00000003
+#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK 0x00000003
+
+#if defined(RTEMS_MULTIPROCESSING)
+ #define LEON3_CLOCK_INDEX \
+ (rtems_configuration_get_user_multiprocessing_table() ? LEON3_Cpu_Index : 0)
+#else
+ #define LEON3_CLOCK_INDEX 0
+#endif
+
+/*
+ * We assume that a boot loader (usually GRMON) initialized the GPTIMER 0 to
+ * run with 1MHz. This is used to determine all clock frequencies of the PnP
+ * devices. See also ambapp_freq_init() and ambapp_freq_get().
+ */
+#define LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER 1000000
+
+/* Load 32-bit word by forcing a cache-miss */
+static inline unsigned int leon_r32_no_cache(uintptr_t addr)
+{
+ unsigned int tmp;
+ __asm__ volatile (" lda [%1] 1, %0\n" : "=r"(tmp) : "r"(addr));
+ return tmp;
+}
+
+/* Let user override which on-chip APBUART will be debug UART
+ * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
+ * 1 = APBUART[0]
+ * 2 = APBUART[1]
+ * 3 = APBUART[2]
+ * ...
+ */
+extern int syscon_uart_index;
+
+/* Let user override which on-chip APBUART will be debug UART
+ * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
+ * 1 = APBUART[0]
+ * 2 = APBUART[1]
+ * 3 = APBUART[2]
+ * ...
+ */
+extern int leon3_debug_uart_index;
+
+/* Let user override which on-chip TIMER core will be used for system clock
+ * timer. This controls which timer core will be accociated with
+ * LEON3_Timer_Regs registers base address. This value will by destroyed during
+ * initialization.
+ * 0 = Default configuration. GPTIMER[0]
+ * 1 = GPTIMER[1]
+ * 2 = GPTIMER[2]
+ * ...
+ */
+extern int leon3_timer_core_index;
+
+/* Let user override system clock timer prescaler. This affects all timer
+ * instances on the system clock timer core determined by
+ * leon3_timer_core_index.
+ * 0 = Default configuration. Use bootloader configured value.
+ * N = Prescaler is set to N. N must not be less that number of timers.
+ * 8 = Prescaler is set to 8 (the fastest prescaler possible on all HW)
+ * ...
+ */
+extern unsigned int leon3_timer_prescaler;
+
+/* GRLIB extended IRQ controller register */
+void leon3_ext_irq_init(void);
+
+void leon3_power_down_loop(void) RTEMS_NO_RETURN;
+
+static inline uint32_t leon3_get_cpu_count(
+ volatile struct irqmp_regs *irqmp
+)
+{
+ uint32_t mpstat = irqmp->mpstat;
+
+ return ((mpstat >> LEON3_IRQMPSTATUS_CPUNR) & 0xf) + 1;
+}
+
+static inline void leon3_set_system_register(uint32_t addr, uint32_t val)
+{
+ __asm__ volatile(
+ "sta %1, [%0] 2"
+ :
+ : "r" (addr), "r" (val)
+ );
+}
+
+static inline uint32_t leon3_get_system_register(uint32_t addr)
+{
+ uint32_t val;
+
+ __asm__ volatile(
+ "lda [%1] 2, %0"
+ : "=r" (val)
+ : "r" (addr)
+ );
+
+ return val;
+}
+
+static inline void leon3_set_cache_control_register(uint32_t val)
+{
+ leon3_set_system_register(0x0, val);
+}
+
+static inline uint32_t leon3_get_cache_control_register(void)
+{
+ return leon3_get_system_register(0x0);
+}
+
+static inline bool leon3_data_cache_snooping_enabled(void)
+{
+ return leon3_get_cache_control_register() & LEON3_REG_CACHE_CTRL_DS;
+}
+
+static inline uint32_t leon3_get_inst_cache_config_register(void)
+{
+ return leon3_get_system_register(0x8);
+}
+
+static inline uint32_t leon3_get_data_cache_config_register(void)
+{
+ return leon3_get_system_register(0xc);
+}
+
+static inline bool leon3_irqmp_has_timestamp(
+ volatile struct irqmp_timestamp_regs *irqmp_ts
+)
+{
+ return (irqmp_ts->control >> 27) > 0;
+}
+
+static inline uint32_t leon3_up_counter_low(void)
+{
+ uint32_t asr23;
+
+ __asm__ volatile (
+ "mov %%asr23, %0"
+ : "=&r" (asr23)
+ );
+
+ return asr23;
+}
+
+static inline uint32_t leon3_up_counter_high(void)
+{
+ uint32_t asr22;
+
+ __asm__ volatile (
+ "mov %%asr22, %0"
+ : "=&r" (asr22)
+ );
+
+ return asr22;
+}
+
+static inline void leon3_up_counter_enable(void)
+{
+ __asm__ volatile (
+ "mov %g0, %asr22"
+ );
+}
+
+static inline bool leon3_up_counter_is_available(void)
+{
+ return leon3_up_counter_low() != leon3_up_counter_low();
+}
+
+static inline uint32_t leon3_up_counter_frequency(void)
+{
+ /*
+ * For simplicity, assume that the interrupt controller uses the processor
+ * clock. This is at least true on the GR740.
+ */
+ return ambapp_freq_get(&ambapp_plb, LEON3_IrqCtrl_Adev);
+}
+
+#endif /* !ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_INCLUDE_LEON_h */
+/* end of include file */
+
diff --git a/bsps/sparc/leon3/include/tm27.h b/bsps/sparc/leon3/include/tm27.h
new file mode 100644
index 0000000000..00921d4880
--- /dev/null
+++ b/bsps/sparc/leon3/include/tm27.h
@@ -0,0 +1,84 @@
+/**
+ * @file
+ * @ingroup sparc_leon3
+ * @brief Implementations for interrupt mechanisms for Time Test 27
+ */
+
+/*
+ * COPYRIGHT (c) 2006.
+ * 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.
+ */
+
+#ifndef _RTEMS_TMTEST27
+#error "This is an RTEMS internal file you must not include directly."
+#endif
+
+#ifndef __tm27_h
+#define __tm27_h
+
+/*
+ * Define the interrupt mechanism for Time Test 27
+ *
+ * NOTE: Since the interrupt code for the SPARC supports both synchronous
+ * and asynchronous trap handlers, support for testing with both
+ * is included.
+ */
+
+#define SIS_USE_SYNCHRONOUS_TRAP 0
+
+/*
+ * The synchronous trap is an arbitrarily chosen software trap.
+ */
+
+#if (SIS_USE_SYNCHRONOUS_TRAP == 1)
+
+#define TEST_VECTOR SPARC_SYNCHRONOUS_TRAP( 0x90 )
+
+#define MUST_WAIT_FOR_INTERRUPT 1
+
+#define Install_tm27_vector( handler ) \
+ set_vector( (handler), TEST_VECTOR, 1 );
+
+#define Cause_tm27_intr() \
+ __asm__ volatile( "ta 0x10; nop " );
+
+#define Clear_tm27_intr() /* empty */
+
+#define Lower_tm27_intr() /* empty */
+
+/*
+ * The asynchronous trap is an arbitrarily chosen ERC32 interrupt source.
+ */
+
+#else /* use a regular asynchronous trap */
+
+#define TEST_INTERRUPT_SOURCE LEON_INTERRUPT_EXTERNAL_1
+#define TEST_VECTOR LEON_TRAP_TYPE( TEST_INTERRUPT_SOURCE )
+#define TEST_INTERRUPT_SOURCE2 LEON_INTERRUPT_EXTERNAL_1+1
+#define TEST_VECTOR2 LEON_TRAP_TYPE( TEST_INTERRUPT_SOURCE2 )
+#define MUST_WAIT_FOR_INTERRUPT 1
+
+#define Install_tm27_vector( handler ) \
+ set_vector( (handler), TEST_VECTOR, 1 ); \
+ set_vector( (handler), TEST_VECTOR2, 1 );
+
+#define Cause_tm27_intr() \
+ do { \
+ LEON_Force_interrupt( TEST_INTERRUPT_SOURCE+(Interrupt_nest>>1)); \
+ nop(); \
+ nop(); \
+ nop(); \
+ } while (0)
+
+#define Clear_tm27_intr() \
+ LEON_Clear_interrupt( TEST_INTERRUPT_SOURCE )
+
+#define Lower_tm27_intr() /* empty */
+
+#endif
+
+#endif