diff options
Diffstat (limited to 'bsps/sparc/leon3')
-rw-r--r-- | bsps/sparc/leon3/headers.am | 13 | ||||
-rw-r--r-- | bsps/sparc/leon3/include/amba.h | 48 | ||||
-rw-r--r-- | bsps/sparc/leon3/include/bsp.h | 250 | ||||
-rw-r--r-- | bsps/sparc/leon3/include/bsp/irq.h | 55 | ||||
-rw-r--r-- | bsps/sparc/leon3/include/bsp/watchdog.h | 49 | ||||
-rw-r--r-- | bsps/sparc/leon3/include/leon.h | 511 | ||||
-rw-r--r-- | bsps/sparc/leon3/include/tm27.h | 84 |
7 files changed, 1010 insertions, 0 deletions
diff --git a/bsps/sparc/leon3/headers.am b/bsps/sparc/leon3/headers.am new file mode 100644 index 0000000000..755a89632d --- /dev/null +++ b/bsps/sparc/leon3/headers.am @@ -0,0 +1,13 @@ +## This file was generated by "./boostrap -H". + +include_HEADERS = +include_HEADERS += ../../../../../../bsps/sparc/leon3/include/amba.h +include_HEADERS += ../../../../../../bsps/sparc/leon3/include/bsp.h +include_HEADERS += include/bspopts.h +include_HEADERS += ../../../../../../bsps/sparc/leon3/include/leon.h +include_HEADERS += ../../../../../../bsps/sparc/leon3/include/tm27.h + +include_bspdir = $(includedir)/bsp +include_bsp_HEADERS = +include_bsp_HEADERS += ../../../../../../bsps/sparc/leon3/include/bsp/irq.h +include_bsp_HEADERS += ../../../../../../bsps/sparc/leon3/include/bsp/watchdog.h 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 |