Changeset 5ad38eac in rtems


Ignore:
Timestamp:
10/12/14 19:10:00 (9 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.11, 5, master
Children:
ff8922c
Parents:
5fdb72a0
git-author:
Joel Sherrill <joel.sherrill@…> (10/12/14 19:10:00)
git-committer:
Joel Sherrill <joel.sherrill@…> (10/13/14 15:33:31)
Message:

powerpc/shared/clock/clock.c: Remove clock major/minor and clean up

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/shared/clock/clock.c

    r5fdb72a0 r5ad38eac  
    4343volatile uint32_t Clock_driver_ticks = 0;
    4444
    45 rtems_device_major_number rtems_clock_major = UINT32_MAX;
    46 
    47 rtems_device_minor_number rtems_clock_minor = UINT32_MAX;
    48 
    4945static uint32_t ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX;
    5046
     
    5551static void ppc_clock_no_tick(void)
    5652{
    57         /* Do nothing */
     53  /* Do nothing */
    5854}
    5955
    6056static void (*ppc_clock_tick)(void) = ppc_clock_no_tick;
    6157
    62 static int ppc_clock_exception_handler( BSP_Exception_frame *frame, unsigned number)
    63 {
    64         uint32_t delta = ppc_clock_decrementer_value;
    65         uint32_t next = ppc_clock_next_time_base;
    66         uint32_t dec = 0;
    67         uint32_t now = 0;
    68         uint32_t msr = 0;
    69 
    70         do {
    71                 /* Increment clock ticks */
    72                 Clock_driver_ticks += 1;
    73 
    74                 /* Enable external exceptions */
    75                 msr = ppc_external_exceptions_enable();
    76 
    77                 /* Call clock ticker  */
    78                 ppc_clock_tick();
    79 
    80                 /* Restore machine state */
    81                 ppc_external_exceptions_disable( msr);
    82 
    83                 /* Next time base */
    84                 next += delta;
    85 
    86                 /* Current time */
    87                 now = ppc_time_base();
    88 
    89                 /* New decrementer value */
    90                 dec = next - now;
    91         } while (dec > delta);
    92 
    93         /* Set decrementer */
    94         ppc_set_decrementer_register( dec);
    95 
    96         /* Expected next time base */
    97         ppc_clock_next_time_base = next;
    98 
    99         return 0;
    100 }
    101 
    102 static int ppc_clock_exception_handler_first( BSP_Exception_frame *frame, unsigned number)
    103 {
    104         /* We have to clear the first pending decrementer exception this way */
    105 
    106         if (ppc_decrementer_register() >= 0x80000000) {
    107                 ppc_clock_exception_handler( frame, number);
    108         }
    109 
    110         ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler);
    111 
    112         return 0;
    113 }
    114 
    115 static int ppc_clock_exception_handler_booke( BSP_Exception_frame *frame, unsigned number)
    116 {
    117         uint32_t msr;
    118 
    119         /* Acknowledge decrementer request */
    120         PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_TSR, BOOKE_TSR_DIS);
    121 
    122         /* Increment clock ticks */
    123         Clock_driver_ticks += 1;
    124 
    125         /* Enable external exceptions */
    126         msr = ppc_external_exceptions_enable();
    127 
    128         /* Call clock ticker  */
    129         ppc_clock_tick();
    130 
    131         /* Restore machine state */
    132         ppc_external_exceptions_disable( msr);
    133 
    134         return 0;
     58static int ppc_clock_exception_handler(
     59  BSP_Exception_frame *frame,
     60  unsigned number
     61)
     62{
     63  uint32_t delta = ppc_clock_decrementer_value;
     64  uint32_t next = ppc_clock_next_time_base;
     65  uint32_t dec = 0;
     66  uint32_t now = 0;
     67  uint32_t msr = 0;
     68
     69  do {
     70    /* Increment clock ticks */
     71    Clock_driver_ticks += 1;
     72
     73    /* Enable external exceptions */
     74    msr = ppc_external_exceptions_enable();
     75
     76    /* Call clock ticker  */
     77    ppc_clock_tick();
     78
     79    /* Restore machine state */
     80    ppc_external_exceptions_disable( msr);
     81
     82    /* Next time base */
     83    next += delta;
     84
     85    /* Current time */
     86    now = ppc_time_base();
     87
     88    /* New decrementer value */
     89    dec = next - now;
     90  } while (dec > delta);
     91
     92  /* Set decrementer */
     93  ppc_set_decrementer_register( dec);
     94
     95  /* Expected next time base */
     96  ppc_clock_next_time_base = next;
     97
     98  return 0;
     99}
     100
     101static int ppc_clock_exception_handler_first(
     102  BSP_Exception_frame *frame,
     103  unsigned number
     104)
     105{
     106  /* We have to clear the first pending decrementer exception this way */
     107
     108  if (ppc_decrementer_register() >= 0x80000000) {
     109    ppc_clock_exception_handler( frame, number);
     110  }
     111
     112  ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler);
     113
     114  return 0;
     115}
     116
     117static int ppc_clock_exception_handler_booke(
     118  BSP_Exception_frame *frame,
     119  unsigned number
     120)
     121{
     122  uint32_t msr;
     123
     124  /* Acknowledge decrementer request */
     125  PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_TSR, BOOKE_TSR_DIS);
     126
     127  /* Increment clock ticks */
     128  Clock_driver_ticks += 1;
     129
     130  /* Enable external exceptions */
     131  msr = ppc_external_exceptions_enable();
     132
     133  /* Call clock ticker  */
     134  ppc_clock_tick();
     135
     136  /* Restore machine state */
     137  ppc_external_exceptions_disable( msr);
     138
     139  return 0;
    135140}
    136141
    137142static int ppc_clock_exception_handler_ppc405(BSP_Exception_frame *frame, unsigned number)
    138143{
    139         uint32_t msr;
    140 
    141         /* Acknowledge PIT request */
    142         PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_TSR, BOOKE_TSR_DIS);
    143 
    144         /* Increment clock ticks */
    145         Clock_driver_ticks += 1;
    146 
    147         /* Enable external exceptions */
    148         msr = ppc_external_exceptions_enable();
    149 
    150         /* Call clock ticker  */
    151         ppc_clock_tick();
    152 
    153         /* Restore machine state */
    154         ppc_external_exceptions_disable(msr);
    155 
    156         return 0;
     144  uint32_t msr;
     145
     146  /* Acknowledge PIT request */
     147  PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_TSR, BOOKE_TSR_DIS);
     148
     149  /* Increment clock ticks */
     150  Clock_driver_ticks += 1;
     151
     152  /* Enable external exceptions */
     153  msr = ppc_external_exceptions_enable();
     154
     155  /* Call clock ticker  */
     156  ppc_clock_tick();
     157
     158  /* Restore machine state */
     159  ppc_external_exceptions_disable(msr);
     160
     161  return 0;
    157162}
    158163
    159164static uint32_t ppc_clock_nanoseconds_since_last_tick(void)
    160165{
    161         uint64_t k = ppc_clock_factor;
    162         uint32_t c = ppc_decrementer_register();
    163         uint32_t i = ppc_clock_decrementer_value + 1;
    164 
    165         return (uint32_t) (((i - c) * k) >> 32);
     166  uint64_t k = ppc_clock_factor;
     167  uint32_t c = ppc_decrementer_register();
     168  uint32_t i = ppc_clock_decrementer_value + 1;
     169
     170  return (uint32_t) (((i - c) * k) >> 32);
    166171}
    167172
    168173static uint32_t ppc_clock_nanoseconds_since_last_tick_ppc405(void)
    169174{
    170         uint64_t k = ppc_clock_factor;
    171         uint32_t i = ppc_clock_decrementer_value;
    172         uint32_t c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT);
    173 
    174         if ((PPC_SPECIAL_PURPOSE_REGISTER(PPC405_TSR) & BOOKE_TSR_DIS) != 0) {
    175                 c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT) + i;
    176         }
    177 
    178         return (uint32_t) ((c * k) >> 32);
     175  uint64_t k = ppc_clock_factor;
     176  uint32_t i = ppc_clock_decrementer_value;
     177  uint32_t c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT);
     178
     179  if ((PPC_SPECIAL_PURPOSE_REGISTER(PPC405_TSR) & BOOKE_TSR_DIS) != 0) {
     180    c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT) + i;
     181  }
     182
     183  return (uint32_t) ((c * k) >> 32);
    179184}
    180185
    181186void Clock_exit(void)
    182187{
    183         /* Set the decrementer to the maximum value */
    184         ppc_set_decrementer_register( PPC_CLOCK_DECREMENTER_MAX);
    185 
    186         /* Use default clock handler */
    187         ppc_clock_tick = ppc_clock_no_tick;
    188 }
    189 
    190 rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
    191 {
    192         uint64_t frequency = bsp_time_base_frequency;
    193         uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
    194         uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
    195 
    196         /* Make major/minor available to others such as shared memory driver */
    197         rtems_clock_major = major;
    198         rtems_clock_minor = minor;
    199 
    200         /*
    201         * Set default ticker.
    202         *
    203         * The function rtems_clock_tick() returns a status code.  This value
    204         * will be discarded since the RTEMS documentation claims that it is
    205         * always successful.
    206         */
    207         ppc_clock_tick = (void (*)(void)) rtems_clock_tick;
    208 
    209         /* Factor for nano seconds extension */
    210         ppc_clock_factor = (1000000000ULL << 32) / frequency;
    211 
    212         if (ppc_cpu_is_bookE() != PPC_BOOKE_405) {
    213                 /* Decrementer value */
    214                 ppc_clock_decrementer_value = interval - 1;
    215 
    216                 /* Check decrementer value */
    217                 if (ppc_clock_decrementer_value == 0) {
    218                         ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX;
    219                         RTEMS_SYSLOG_ERROR( "decrementer value would be zero, will be set to maximum value instead\n");
    220                 }
    221 
    222                 /* Set the nanoseconds since last tick handler */
    223                 rtems_clock_set_nanoseconds_extension( ppc_clock_nanoseconds_since_last_tick);
    224 
    225                 if (ppc_cpu_is_bookE()) {
    226                         /* Set decrementer auto-reload value */
    227                         PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_DECAR, ppc_clock_decrementer_value);
    228 
    229                         /* Install exception handler */
    230                         ppc_exc_set_handler( ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_booke);
    231 
    232                         /* Enable decrementer and auto-reload */
    233                         PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
    234                 } else {
    235                         /* Here the decrementer value is actually the interval */
    236                         ++ppc_clock_decrementer_value;
    237 
    238                         /* Initialize next time base */
    239                         ppc_clock_next_time_base = ppc_time_base() + ppc_clock_decrementer_value;
    240 
    241                         /* Install exception handler */
    242                         ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler_first);
    243                 }
    244 
    245                 /* Set the decrementer value */
    246                 ppc_set_decrementer_register( ppc_clock_decrementer_value);
    247         } else {
    248                 /* PIT interval value */
    249                 ppc_clock_decrementer_value = interval;
    250 
    251                 /* Set the nanoseconds since last tick handler */
    252                 rtems_clock_set_nanoseconds_extension(ppc_clock_nanoseconds_since_last_tick_ppc405);
    253 
    254                 /* Install exception handler */
    255                 ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_ppc405);
    256 
    257                 /* Enable PIT and auto-reload */
    258                 PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(PPC405_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
    259 
    260                 /* Set PIT auto-reload and initial value */
    261                 PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_PIT, interval);
    262         }
    263 
    264         return RTEMS_SUCCESSFUL;
    265 }
     188  /* Set the decrementer to the maximum value */
     189  ppc_set_decrementer_register( PPC_CLOCK_DECREMENTER_MAX);
     190
     191  /* Use default clock handler */
     192  ppc_clock_tick = ppc_clock_no_tick;
     193}
     194
     195rtems_device_driver Clock_initialize(
     196  rtems_device_major_number major,
     197  rtems_device_minor_number minor,
     198  void *arg
     199)
     200{
     201  uint64_t frequency = bsp_time_base_frequency;
     202  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
     203  uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
     204
     205  /*
     206  * Set default ticker.
     207  *
     208  * The function rtems_clock_tick() returns a status code.  This value
     209  * will be discarded since the RTEMS documentation claims that it is
     210  * always successful.
     211  */
     212  ppc_clock_tick = (void (*)(void)) rtems_clock_tick;
     213
     214  /* Factor for nano seconds extension */
     215  ppc_clock_factor = (1000000000ULL << 32) / frequency;
     216
     217  if (ppc_cpu_is_bookE() != PPC_BOOKE_405) {
     218    /* Decrementer value */
     219    ppc_clock_decrementer_value = interval - 1;
     220
     221    /* Check decrementer value */
     222    if (ppc_clock_decrementer_value == 0) {
     223      ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX;
     224      RTEMS_SYSLOG_ERROR( "decrementer value would be zero, will be set to maximum value instead\n");
     225    }
     226
     227    /* Set the nanoseconds since last tick handler */
     228    rtems_clock_set_nanoseconds_extension( ppc_clock_nanoseconds_since_last_tick);
     229
     230    if (ppc_cpu_is_bookE()) {
     231      /* Set decrementer auto-reload value */
     232      PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_DECAR, ppc_clock_decrementer_value);
     233
     234      /* Install exception handler */
     235      ppc_exc_set_handler( ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_booke);
     236
     237      /* Enable decrementer and auto-reload */
     238      PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
     239    } else {
     240      /* Here the decrementer value is actually the interval */
     241      ++ppc_clock_decrementer_value;
     242
     243      /* Initialize next time base */
     244      ppc_clock_next_time_base = ppc_time_base() + ppc_clock_decrementer_value;
     245
     246      /* Install exception handler */
     247      ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler_first);
     248    }
     249
     250    /* Set the decrementer value */
     251    ppc_set_decrementer_register( ppc_clock_decrementer_value);
     252  } else {
     253    /* PIT interval value */
     254    ppc_clock_decrementer_value = interval;
     255
     256    /* Set the nanoseconds since last tick handler */
     257    rtems_clock_set_nanoseconds_extension(ppc_clock_nanoseconds_since_last_tick_ppc405);
     258
     259    /* Install exception handler */
     260    ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_ppc405);
     261
     262    /* Enable PIT and auto-reload */
     263    PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(PPC405_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
     264
     265    /* Set PIT auto-reload and initial value */
     266    PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_PIT, interval);
     267  }
     268
     269  return RTEMS_SUCCESSFUL;
     270}
Note: See TracChangeset for help on using the changeset viewer.