Changeset 48cbd63 in rtems


Ignore:
Timestamp:
Jul 31, 2018, 5:19:33 AM (15 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
529154b
Parents:
71284ce
git-author:
Sebastian Huber <sebastian.huber@…> (07/31/18 05:19:33)
git-committer:
Sebastian Huber <sebastian.huber@…> (08/01/18 08:07:18)
Message:

bsp/riscv: Fix clock driver

Do not assume that mtime is zero at boot time.

Update #3433.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • bsps/riscv/riscv/clock/clockdrv.c

    r71284ce r48cbd63  
    5151  struct timecounter base;
    5252  volatile RISCV_CLINT_regs *clint;
     53  uint32_t interval;
    5354} riscv_timecounter;
    5455
    5556static riscv_timecounter riscv_clock_tc;
    5657
    57 static uint32_t riscv_clock_interval;
     58static void riscv_clock_write_mtimecmp(
     59  volatile RISCV_CLINT_timer_reg *mtimecmp,
     60  uint64_t value
     61)
     62{
     63#if __riscv_xlen == 32
     64  mtimecmp->val_32[0] = 0xffffffff;
     65  mtimecmp->val_32[1] = (uint32_t) (value >> 32);
     66  mtimecmp->val_32[0] = (uint32_t) value;
     67#elif __riscv_xlen == 64
     68  mtimecmp->val_64 = value;
     69#endif
     70}
     71
     72static uint64_t riscv_clock_read_mtime(volatile RISCV_CLINT_timer_reg *mtime)
     73{
     74#if __riscv_xlen == 32
     75  uint32_t low;
     76  uint32_t high_0;
     77  uint32_t high_1;
     78
     79  do {
     80    high_0 = mtime->val_32[1];
     81    low = mtime->val_32[0];
     82    high_1 = mtime->val_32[1];
     83  } while (high_0 != high_1);
     84
     85  return (((uint64_t) high_0) << 32) | low;
     86#elif __riscv_xlen == 64
     87  return mtime->val_64;
     88#endif
     89}
    5890
    5991static void riscv_clock_at_tick(riscv_timecounter *tc)
    6092{
    6193  volatile RISCV_CLINT_regs *clint;
    62   uint64_t cmp;
     94  uint64_t value;
    6395
    6496  clint = tc->clint;
    6597
    66   cmp = clint->mtimecmp[0].val_64;
    67   cmp += riscv_clock_interval;
    68 
    69 #if __riscv_xlen == 32
    70   clint->mtimecmp[0].val_32[0] = 0xffffffff;
    71   clint->mtimecmp[0].val_32[1] = (uint32_t) (cmp >> 32);
    72   clint->mtimecmp[0].val_32[0] = (uint32_t) cmp;
    73 #elif __riscv_xlen == 64
    74   clint->mtimecmp[0].val_64 = cmp;
    75 #endif
     98  value = clint->mtimecmp[0].val_64;
     99  value += tc->interval;
     100
     101  riscv_clock_write_mtimecmp(&clint->mtimecmp[0], value);
    76102}
    77103
     
    121147  const char *fdt;
    122148  riscv_timecounter *tc;
     149  volatile RISCV_CLINT_regs *clint;
    123150  uint32_t tb_freq;
    124151  uint64_t us_per_tick;
     152  uint32_t interval;
    125153
    126154  fdt = bsp_fdt_get();
    127 
    128   tc = &riscv_clock_tc;
    129   tc->clint = riscv_clint;
    130 
    131155  tb_freq = riscv_clock_get_timebase_frequency(fdt);
    132156  us_per_tick = rtems_configuration_get_microseconds_per_tick();
    133   riscv_clock_interval = (uint32_t) ((tb_freq * us_per_tick) / 1000000);
    134 
    135   riscv_clock_at_tick(tc);
     157  interval = (uint32_t) ((tb_freq * us_per_tick) / 1000000);
     158  clint = riscv_clint;
     159  tc = &riscv_clock_tc;
     160
     161  tc->clint = clint;
     162  tc->interval = interval;
     163
     164  riscv_clock_write_mtimecmp(
     165    &clint->mtimecmp[0],
     166    riscv_clock_read_mtime(&clint->mtime) + interval
     167  );
    136168
    137169  /* Enable mtimer interrupts */
Note: See TracChangeset for help on using the changeset viewer.