sifive / freedom-metal

Bare Metal Compatibility Library for the Freedom Platform
Other
154 stars 47 forks source link

Possible bug in metal_cpu_get_mtime() #249

Open m3x1m0m opened 4 years ago

m3x1m0m commented 4 years ago

Under 9.3 in the SiFive FE310-G002 Manual one can read the following.

mtime is a 64-bit read-write register that contains the number of cycles counted from the rtcclk input described in Chapter 13. A timer interrupt is pending whenever mtime is greater than or equal to the value in the mtimecmp register. The timer interrupt is reflected in the mtip bit of the mip register described in Chapter 8. On reset, mtime is cleared to zero. The mtimecmp registers are not res

When I take the sifive-welcome example and modify it slightly as displayed below

void wait_for_timer(struct metal_led *which_led) {

    // clear global timer isr flag
    timer_isr_flag = 0;

    // Turn on desired LED
    metal_led_on(which_led);

    // +++++++ mod begin
    printf("t0> %d\n", metal_cpu_get_mtime(cpu0));
    // +++++++ mod end
    // Set timer
    metal_cpu_set_mtimecmp(cpu0, metal_cpu_get_mtime(cpu0) + RTC_FREQ);

    // Enable Timer interrupt
    metal_interrupt_enable(tmr_intr, tmr_id);

    // wait till timer triggers and isr is hit
    while (timer_isr_flag == 0){
    // +++++++ mod begin
      printf("t1> %d\n", metal_cpu_get_mtime(cpu0));
    // +++++++ mod end
    };

    timer_isr_flag = 0;

    // Turn off this LED
    metal_led_off(which_led);
}

I get the output

t0> 0
t1> 0
t1> 0
...
t1> 0
t0> 0
...

which makes me believe, that the register is not read correctly by the function _metal_cpu_getmtime(), is it?

gaoshancha commented 2 years ago

Did you ever find a resolution to this? I am also seeing the same behavior. And in fact, when my interrupt callback is called and I try to read mtime by calling metal_cpu_get_mtime(), it seems to cause my HiFive 1 Rev B CPU to go into a failure state. When I pause the debugger it has the execution in "_metal_shutdown_exit()".