Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:08

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsSPARCLEON3
0007  *
0008  * @brief This header file provides interfaces used by the BSP implementation.
0009  */
0010 
0011 /*
0012  * Copyright (C) 2014, 2023 embedded brains GmbH & Co. KG
0013  *
0014  * Copyright (C) 2015 Cobham Gaisler AB
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifndef LIBBSP_SPARC_LEON3_BSP_LEON3_H
0039 #define LIBBSP_SPARC_LEON3_BSP_LEON3_H
0040 
0041 #include <grlib/apbuart-regs.h>
0042 #include <grlib/gptimer-regs.h>
0043 
0044 #include <bspopts.h>
0045 #include <bsp/irqimpl.h>
0046 
0047 #if !defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
0048 #include <grlib/ambapp.h>
0049 #endif
0050 
0051 #include <sys/timetc.h>
0052 
0053 #ifdef __cplusplus
0054 extern "C" {
0055 #endif
0056 
0057 /**
0058  * @addtogroup RTEMSBSPsSPARCLEON3
0059  *
0060  * @{
0061  */
0062 
0063 /**
0064  * @brief Sets %asr19 to zero to enter the power-down mode of the processor in
0065  *   an infinite loop.
0066  */
0067 RTEMS_NO_RETURN void leon3_power_down_loop( void );
0068 
0069 /**
0070  * @brief This constant represents the flush instruction cache flag of the LEON
0071  *   cache control register.
0072  */
0073 #define LEON3_REG_CACHE_CTRL_FI 0x00200000U
0074 
0075 /**
0076  * @brief This constant represents the data cache snooping enable flag of the
0077  *   LEON cache control register.
0078  */
0079 #define LEON3_REG_CACHE_CTRL_DS 0x00800000U
0080 
0081 /**
0082  * @brief Sets the ASI 0x2 system register value.
0083  *
0084  * @param addr is the address of the ASI 0x2 system register.
0085  *
0086  * @param val is the value to set.
0087  */
0088 static inline void leon3_set_system_register( uint32_t addr, uint32_t val )
0089 {
0090   __asm__ volatile(
0091     "sta %1, [%0] 2"
0092     :
0093     : "r" ( addr ), "r" ( val )
0094   );
0095 }
0096 
0097 /**
0098  * @brief Gets the ASI 0x2 system register value.
0099  *
0100  * @param addr is the address of the ASI 0x2 system register.
0101  *
0102  * @return Returns the register value.
0103  */
0104 static inline uint32_t leon3_get_system_register( uint32_t addr )
0105 {
0106   uint32_t val;
0107 
0108   __asm__ volatile(
0109     "lda [%1] 2, %0"
0110     : "=r" ( val )
0111     : "r" ( addr )
0112   );
0113 
0114   return val;
0115 }
0116 
0117 /**
0118  * @brief Sets the LEON cache control register value.
0119  *
0120  * @param val is the value to set.
0121  */
0122 static inline void leon3_set_cache_control_register( uint32_t val )
0123 {
0124   leon3_set_system_register( 0x0, val );
0125 }
0126 
0127 /**
0128  * @brief Gets the LEON cache control register value.
0129  *
0130  * @return Returns the register value.
0131  */
0132 static inline uint32_t leon3_get_cache_control_register( void )
0133 {
0134   return leon3_get_system_register( 0x0 );
0135 }
0136 
0137 /**
0138  * @brief Checks if the data cache snooping is enabled.
0139  *
0140  * @return Returns true, if the data cache snooping is enabled, otherwise
0141  *   false.
0142  */
0143 static inline bool leon3_data_cache_snooping_enabled( void )
0144 {
0145   return ( leon3_get_cache_control_register() & LEON3_REG_CACHE_CTRL_DS ) != 0;
0146 }
0147 
0148 /**
0149  * @brief Gets the LEON instruction cache configuration register value.
0150  *
0151  * @return Returns the register value.
0152  */
0153 static inline uint32_t leon3_get_inst_cache_config_register( void )
0154 {
0155   return leon3_get_system_register( 0x8 );
0156 }
0157 
0158 /**
0159  * @brief Gets the LEON data cache configuration register value.
0160  *
0161  * @return Returns the register value.
0162  */
0163 static inline uint32_t leon3_get_data_cache_config_register( void )
0164 {
0165   return leon3_get_system_register( 0xc );
0166 }
0167 
0168 /**
0169  * @brief Gets the processor count.
0170  *
0171  * @param[in] regs is the IRQ(A)MP register block address.
0172  *
0173  * @return Returns the processor count.
0174  */
0175 static inline uint32_t leon3_get_cpu_count( const irqamp *regs )
0176 {
0177   return IRQAMP_MPSTAT_NCPU_GET( grlib_load_32( &regs->mpstat ) ) + 1;
0178 }
0179 
0180 #if !defined(LEON3_GPTIMER_BASE)
0181 /**
0182  * @brief This object lets the user override which on-chip GPTIMER core will be
0183  *   used for system clock timer.
0184  *
0185  * This controls which timer core will be accociated with LEON3_Timer_Regs
0186  * registers base address. This value will by destroyed during initialization.
0187  *
0188  * * 0 = Default configuration. GPTIMER[0]
0189  *
0190  * * 1 = GPTIMER[1]
0191  *
0192  * * 2 = GPTIMER[2]
0193  *
0194  * * ...
0195  */
0196 extern int leon3_timer_core_index;
0197 
0198 /**
0199  * @brief This object lets the user override system clock timer prescaler.
0200  *
0201  * This affects all timer instances on the system clock timer core determined
0202  * by ::leon3_timer_core_index.
0203  *
0204  * * 0 = Default configuration. Use bootloader configured value.
0205  *
0206  * * N = Prescaler is set to N. N must not be less that number of timers.
0207  *
0208  * * 8 = Prescaler is set to 8 (the fastest prescaler possible on all HW)
0209  *
0210  * * ...
0211  */
0212 extern unsigned int leon3_timer_prescaler;
0213 #endif
0214 
0215 /**
0216  * @brief This constant defines the index of the GPTIMER timer used by the
0217  *   clock driver.
0218  */
0219 #if defined(RTEMS_MULTIPROCESSING)
0220 #define LEON3_CLOCK_INDEX \
0221   ( leon3_timer_core_index != 0 ? 0 : 2 * LEON3_Cpu_Index )
0222 #else
0223 #define LEON3_CLOCK_INDEX 0
0224 #endif
0225 
0226 /**
0227  * @brief This constant defines the index of the GPTIMER timer used by the
0228  *   CPU counter if the CPU counter uses the GPTIMER.
0229  */
0230 #define LEON3_COUNTER_GPTIMER_INDEX ( LEON3_CLOCK_INDEX + 1 )
0231 
0232 /**
0233  * @brief This constant defines the frequency set by the boot loader of the
0234  *   first GPTIMER instance.
0235  *
0236  * We assume that a boot loader (usually GRMON) initialized the GPTIMER 0 to
0237  * run with 1MHz.  This is used to determine all clock frequencies of the PnP
0238  * devices.  See also ambapp_freq_init() and ambapp_freq_get().
0239  */
0240 #define LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER 1000000
0241 
0242 /**
0243  * @brief This pointer provides the GPTIMER register block address.
0244  */
0245 #if defined(LEON3_GPTIMER_BASE)
0246 #define LEON3_Timer_Regs ((gptimer *) LEON3_GPTIMER_BASE)
0247 #else
0248 extern gptimer *LEON3_Timer_Regs;
0249 
0250 /**
0251  * @brief This pointer provides the GPTIMER device information block.
0252  */
0253 extern struct ambapp_dev *LEON3_Timer_Adev;
0254 #endif
0255 
0256 /**
0257  * @brief Gets the processor local bus frequency in Hz.
0258  *
0259  * @return Returns the frequency.
0260  */
0261 static inline uint32_t leon3_processor_local_bus_frequency( void )
0262 {
0263 #if defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
0264   return ( grlib_load_32( &LEON3_Timer_Regs->sreload ) + 1 ) *
0265     LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER;
0266 #else
0267   /*
0268    * For simplicity, assume that the interrupt controller uses the processor
0269    * clock.  This is at least true on the GR740.
0270    */
0271   return ambapp_freq_get( ambapp_plb(), LEON3_IrqCtrl_Adev );
0272 #endif
0273 }
0274 
0275 /**
0276  * @brief Gets the LEON up-counter low register (%ASR23) value.
0277  *
0278  * @return Returns the register value.
0279  */
0280 static inline uint32_t leon3_up_counter_low( void )
0281 {
0282   uint32_t asr23;
0283 
0284   __asm__ volatile (
0285     "mov %%asr23, %0"
0286     : "=&r" (asr23)
0287   );
0288 
0289   return asr23;
0290 }
0291 
0292 /**
0293  * @brief Gets the LEON up-counter high register (%ASR22) value.
0294  *
0295  * @return Returns the register value.
0296  */
0297 static inline uint32_t leon3_up_counter_high(void)
0298 {
0299   uint32_t asr22;
0300 
0301   __asm__ volatile (
0302     "mov %%asr22, %0"
0303     : "=&r" (asr22)
0304   );
0305 
0306   return asr22;
0307 }
0308 
0309 /**
0310  * @brief Enables the LEON up-counter.
0311  */
0312 static inline void leon3_up_counter_enable( void )
0313 {
0314   __asm__ volatile (
0315     "mov %g0, %asr22"
0316   );
0317 }
0318 
0319 #if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER)
0320 /**
0321  * @brief Checks if the LEON up-counter is available.
0322  *
0323  * The LEON up-counter must have been enabled.
0324  *
0325  * @return Returns true, if the LEON up-counter is available, otherwise false.
0326  */
0327 static inline bool leon3_up_counter_is_available( void )
0328 {
0329   return leon3_up_counter_low() != leon3_up_counter_low();
0330 }
0331 #endif
0332 
0333 /**
0334  * @brief Gets the LEON up-counter frequency in Hz.
0335  *
0336  * @return Returns the frequency.
0337  */
0338 static inline uint32_t leon3_up_counter_frequency( void )
0339 {
0340   return leon3_processor_local_bus_frequency();
0341 }
0342 
0343 /**
0344  * @brief This pointer provides the debug APBUART register block address.
0345  */
0346 #if defined(LEON3_APBUART_BASE)
0347 #define leon3_debug_uart ((struct apbuart *) LEON3_APBUART_BASE)
0348 #else
0349 extern apbuart *leon3_debug_uart;
0350 #endif
0351 
0352 /**
0353  * @brief Represents the LEON3-specific timecounter.
0354  */
0355 typedef struct {
0356   /**
0357    * @brief This member contains the base timecounter.
0358    */
0359   struct timecounter base;
0360 
0361 #if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER)
0362   /**
0363    * @brief This member provides a software fall-back counter.
0364    */
0365   uint32_t software_counter;
0366 
0367   /**
0368    * @brief This member may reference a hardware counter register.
0369    */
0370   volatile uint32_t *counter_register;
0371 #endif
0372 } leon3_timecounter;
0373 
0374 /**
0375  * @brief Provides the LEON3-specific timecounter.
0376  *
0377  * It is also used by the CPU counter implementation.
0378  */
0379 extern leon3_timecounter leon3_timecounter_instance;
0380 
0381 #if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
0382 /**
0383  * @brief This interrupt lock prevents concurrent access to L2C registers.
0384  *
0385  * This is required as a workaround for the in GR740 errata: Level-2 Cache
0386  * Issues H1 2023 (GRLIB-TN-0021).
0387  */
0388 extern rtems_interrupt_lock leon3_l2c_lock;
0389 #endif
0390 
0391 /** @} */
0392 
0393 #ifdef __cplusplus
0394 }
0395 #endif
0396 
0397 #endif /* LIBBSP_SPARC_LEON3_BSP_LEON3_H */