26 #include <bsp/fatal.h> 30 #include <rtems/score/sparcimpl.h> 39 #ifndef RTEMS_DRVMGR_STARTUP 44 static void (*leon3_tc_tick)(void);
48 #ifdef RTEMS_PROFILING 49 #define IRQMP_TIMESTAMP_S1_S2 ((1U << 25) | (1U << 26)) 51 static void leon3_tc_tick_irqmp_timestamp(
void)
54 &LEON3_IrqCtrl_Regs->timestamp[0];
55 unsigned int first = irqmp_ts->assertion;
56 unsigned int second = irqmp_ts->counter;
58 irqmp_ts->control |= IRQMP_TIMESTAMP_S1_S2;
66 static void leon3_tc_tick_irqmp_timestamp_init(
void)
68 #ifdef RTEMS_PROFILING 75 static Atomic_Uint counter = ATOMIC_INITIALIZER_UINT(0);
78 _Atomic_Fetch_add_uint(&counter, 1, ATOMIC_ORDER_RELAXED)
85 &LEON3_IrqCtrl_Regs->timestamp[0];
86 unsigned int ks = 1U << 5;
88 irqmp_ts->control = ks | IRQMP_TIMESTAMP_S1_S2 | (
unsigned int) clkirq;
91 leon3_tc_tick = leon3_tc_tick_irqmp_timestamp;
98 static void leon3_tc_tick_default(
void)
104 counter = &_SPARC_Counter_mutable;
107 LEON3_IrqCtrl_Regs->iclear = counter->pending_mask;
108 counter->accumulated += counter->interval;
116 static void leon3_tc_do_tick(
void)
121 #define Adjust_clkirq_for_node() do { clkirq += LEON3_CLOCK_INDEX; } while(0) 123 #define Clock_driver_support_find_timer() \ 126 if (LEON3_Timer_Regs) { \ 127 clkirq = (LEON3_Timer_Regs->cfg & 0xf8) >> 3; \ 129 Adjust_clkirq_for_node(); \ 133 #define Clock_driver_support_install_isr( _new ) \ 134 bsp_clock_handler_install(_new) 136 static void bsp_clock_handler_install(
rtems_isr *
new)
152 #define Clock_driver_support_set_interrupt_affinity(online_processors) \ 153 bsp_interrupt_set_affinity(clkirq, online_processors) 155 static void leon3_clock_initialize(
void)
161 irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
162 gpt = LEON3_Timer_Regs;
165 gpt->timer[LEON3_CLOCK_INDEX].reload =
167 gpt->timer[LEON3_CLOCK_INDEX].ctrl =
168 GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_RS |
169 GPTIMER_TIMER_CTRL_LD | GPTIMER_TIMER_CTRL_IE;
171 leon3_up_counter_enable();
173 if (leon3_up_counter_is_available()) {
175 tc->tc_get_timecount = _SPARC_Get_timecount_asr23;
176 tc->tc_frequency = leon3_up_counter_frequency();
178 #ifdef RTEMS_PROFILING 179 if (!leon3_irqmp_has_timestamp(irqmp_ts)) {
180 bsp_fatal(LEON3_FATAL_CLOCK_NO_IRQMP_TIMESTAMP_SUPPORT);
184 leon3_tc_tick = leon3_tc_tick_irqmp_timestamp_init;
185 }
else if (leon3_irqmp_has_timestamp(irqmp_ts)) {
187 tc->tc_get_timecount = _SPARC_Get_timecount_up;
188 tc->tc_frequency = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev);
190 leon3_tc_tick = leon3_tc_tick_irqmp_timestamp_init;
196 irqmp_ts->control = 0x1;
204 gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].ctrl =
205 GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_IE;
207 tc->tc_get_timecount = _SPARC_Get_timecount_down;
211 counter = &_SPARC_Counter_mutable;
212 counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled;
213 counter->read = _SPARC_Counter_read_clock;
214 counter->counter_register = &gpt->timer[LEON3_CLOCK_INDEX].value;
215 counter->pending_register = &LEON3_IrqCtrl_Regs->ipend;
216 counter->pending_mask = UINT32_C(1) << clkirq;
220 tc->tc_get_timecount = _SPARC_Get_timecount_clock;
223 tc->tc_frequency = LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER,
224 leon3_tc_tick = leon3_tc_tick_default;
227 tc->tc_counter_mask = 0xffffffff;
232 #define Clock_driver_support_initialize_hardware() \ 233 leon3_clock_initialize() 235 #define Clock_driver_timecounter_tick() leon3_tc_do_tick() 237 #include "../../../shared/dev/clock/clockimpl.h"
static RTEMS_NO_RETURN void rtems_fatal(rtems_fatal_source fatal_source, rtems_fatal_code error_code)
%
rtems_status_code rtems_interrupt_handler_install(rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
Installs the interrupt handler routine handler for the interrupt vector with number vector...
static __inline__ void rtems_timecounter_install(struct timecounter *tc)
Installs the timecounter.
This status code indicates successful completion.
#define rtems_interrupt_local_enable(_isr_cookie)
%
ISR_Level rtems_interrupt_level
%
rtems_status_code
This enumeration provides status codes for directives of the Classic API.
#define RTEMS_INTERRUPT_UNIQUE
Makes the interrupt handler unique. Prevents other handler from using the same interrupt vector...
This header file defines the Interrupt Manager API.
static void _Profiling_Update_max_interrupt_delay(Per_CPU_Control *cpu, CPU_Counter_ticks interrupt_delay)
Updates the maximum interrupt delay.
#define rtems_configuration_get_microseconds_per_tick()
Returns the number of microseconds per clock tick configured for this application.
#define rtems_scheduler_get_processor_maximum()
Returns the processor maximum supported by the system.
Fatal source for BSP errors.
static __inline__ void rtems_timecounter_tick(void)
Performs a timecounter tick.
LEON3 generic shared IRQ setup.
#define RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER
Timecounter quality for the clock drivers.
#define rtems_interrupt_local_disable(_isr_cookie)
%