File indexing completed on 2025-05-11 08:24:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <bsp.h>
0038 #include <bsp/fatal.h>
0039 #include <bsp/irq.h>
0040 #include <bsp/irq-generic.h>
0041 #include <dev/clock/arm-generic-timer.h>
0042
0043 #include <rtems/counter.h>
0044 #include <rtems/sysinit.h>
0045 #include <rtems/timecounter.h>
0046 #include <rtems/score/smpimpl.h>
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 typedef struct {
0068 struct timecounter tc;
0069 uint32_t interval;
0070 rtems_vector_number irq;
0071 } arm_gt_clock_context;
0072
0073 static arm_gt_clock_context arm_gt_clock_instance;
0074
0075 static void arm_gt_clock_at_tick(arm_gt_clock_context *ctx)
0076 {
0077 uint64_t cval;
0078 uint32_t interval;
0079
0080 interval = ctx->interval;
0081 cval = arm_gt_clock_get_compare_value();
0082 cval += interval;
0083 arm_gt_clock_set_compare_value(cval);
0084 #ifdef ARM_GENERIC_TIMER_UNMASK_AT_TICK
0085 arm_gt_clock_set_control(0x1);
0086 #endif
0087 }
0088
0089 static rtems_interrupt_entry arm_gt_interrupt_entry;
0090
0091 static void arm_gt_clock_handler_install(rtems_interrupt_handler handler)
0092 {
0093 rtems_status_code sc;
0094
0095 rtems_interrupt_entry_initialize(
0096 &arm_gt_interrupt_entry,
0097 handler,
0098 &arm_gt_clock_instance,
0099 "Clock"
0100 );
0101 sc = rtems_interrupt_entry_install(
0102 arm_gt_clock_instance.irq,
0103 RTEMS_INTERRUPT_UNIQUE,
0104 &arm_gt_interrupt_entry
0105 );
0106 if (sc != RTEMS_SUCCESSFUL) {
0107 bsp_fatal(BSP_ARM_FATAL_GENERIC_TIMER_CLOCK_IRQ_INSTALL);
0108 }
0109 }
0110
0111 static uint32_t arm_gt_clock_get_timecount(struct timecounter *tc)
0112 {
0113 return (uint32_t) arm_gt_clock_get_count();
0114 }
0115
0116 static void arm_gt_clock_gt_init(uint64_t cval)
0117 {
0118 arm_gt_clock_set_compare_value(cval);
0119 arm_gt_clock_set_control(0x1);
0120 }
0121
0122 #if defined(RTEMS_SMP) && !defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
0123 static void arm_gt_clock_secondary_action(void *arg)
0124 {
0125 uint64_t *cval;
0126
0127 cval = arg;
0128 arm_gt_clock_gt_init(*cval);
0129 bsp_interrupt_vector_enable(arm_gt_clock_instance.irq);
0130 }
0131 #endif
0132
0133 static void arm_gt_clock_secondary_initialization(uint64_t cval)
0134 {
0135 #if defined(RTEMS_SMP) && !defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
0136 _SMP_Broadcast_action(arm_gt_clock_secondary_action, &cval);
0137 #endif
0138 }
0139
0140 static void arm_gt_clock_initialize(void)
0141 {
0142 uint64_t frequency;
0143 uint64_t us_per_tick;
0144 uint32_t interval;
0145 uint64_t cval;
0146 struct timecounter *tc;
0147
0148 tc = &arm_gt_clock_instance.tc;
0149 frequency = tc->tc_frequency;
0150 us_per_tick = rtems_configuration_get_microseconds_per_tick();
0151 interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
0152 cval = arm_gt_clock_get_count();
0153 cval += interval;
0154 arm_gt_clock_instance.interval = interval;
0155
0156 arm_gt_clock_gt_init(cval);
0157 arm_gt_clock_secondary_initialization(cval);
0158
0159 tc->tc_get_timecount = arm_gt_clock_get_timecount;
0160 tc->tc_counter_mask = 0xffffffff;
0161 tc->tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
0162 rtems_timecounter_install(tc);
0163 }
0164
0165 uint32_t _CPU_Counter_frequency(void)
0166 {
0167 return (uint32_t) arm_gt_clock_instance.tc.tc_frequency;
0168 }
0169
0170 CPU_Counter_ticks _CPU_Counter_read(void)
0171 {
0172 return (uint32_t) arm_gt_clock_get_count();
0173 }
0174
0175 static void arm_gt_system_init(void)
0176 {
0177 #ifdef ARM_GENERIC_TIMER_SYSTEM_BASE
0178 volatile uint32_t *cntcr;
0179
0180 cntcr = (volatile uint32_t *) ARM_GENERIC_TIMER_SYSTEM_BASE;
0181 *cntcr = ARM_GENERIC_TIMER_SYSTEM_CNTCR;
0182 #endif
0183 }
0184
0185 static void arm_gt_clock_early_init(void)
0186 {
0187 uint32_t frequency;
0188
0189 arm_gt_system_init();
0190 arm_gt_clock_set_control(0x3);
0191 arm_generic_timer_get_config(
0192 &frequency,
0193 &arm_gt_clock_instance.irq
0194 );
0195
0196
0197
0198
0199
0200 arm_gt_clock_instance.tc.tc_frequency = frequency;
0201 }
0202
0203 RTEMS_SYSINIT_ITEM(
0204 arm_gt_clock_early_init,
0205 RTEMS_SYSINIT_CPU_COUNTER,
0206 RTEMS_SYSINIT_ORDER_FIRST
0207 );
0208
0209 #define Clock_driver_support_at_tick(arg) \
0210 arm_gt_clock_at_tick(arg)
0211
0212 #define Clock_driver_support_initialize_hardware() \
0213 arm_gt_clock_initialize()
0214
0215 #define Clock_driver_support_install_isr(isr) \
0216 arm_gt_clock_handler_install(isr)
0217
0218
0219
0220
0221 #include "../../shared/dev/clock/clockimpl.h"