test_cpu_speed.tcl 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. # SPDX-License-Identifier: GPL-2.0-or-later
  2. # Description:
  3. # Measure the CPU clock frequency of an ARM Cortex-M based device.
  4. #
  5. # Return:
  6. # The CPU clock frequency in Hz. A negative value indicates that the loop
  7. # counter was saturated.
  8. #
  9. # Note:
  10. # You may need to adapt the number of cycles for your device.
  11. #
  12. add_help_text cortex_m_test_cpu_speed "Measure the CPU clock frequency of an ARM Cortex-M based device"
  13. add_usage_text cortex_m_test_cpu_speed {address [timeout [cycles_per_loop]]}
  14. proc cortex_m_test_cpu_speed { address { timeout 200 } { cycles_per_loop 4 } } {
  15. set loop_counter_start 0xffffffff
  16. halt
  17. # Backup registers and memory.
  18. set backup_regs [get_reg -force {pc r0 xpsr}]
  19. set backup_mem [read_memory $address 16 3]
  20. # We place the following code at the given address to measure the
  21. # CPU clock frequency:
  22. #
  23. # 3801: subs r0, #1
  24. # d1fd: bne #-2
  25. # e7fe: b #-4
  26. write_memory $address 16 {0x3801 0xd1fd 0xe7fe}
  27. set_reg "pc $address r0 $loop_counter_start"
  28. resume
  29. sleep $timeout
  30. halt
  31. # Get the loop counter value from register r0.
  32. set loop_counter_end [dict values [get_reg r0]]
  33. set loop_counter_diff [expr {$loop_counter_start - $loop_counter_end}]
  34. # Restore registers and memory.
  35. set_reg $backup_regs
  36. write_memory $address 16 $backup_mem
  37. if { [expr {$loop_counter_end == 0}] } {
  38. return -1
  39. }
  40. return [expr {double($loop_counter_diff) * $cycles_per_loop / $timeout * 1000}]
  41. }