Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cycle counter driver and test app #386

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions examples/tests/cycle_count/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Makefile for user application

# Specify this directory relative to the current application.
TOCK_USERLAND_BASE_DIR = ../../..

# Which files to compile.
C_SRCS := $(wildcard *.c)

# Include userland master makefile. Contains rules and flags for actually
# building the application.
include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk
5 changes: 5 additions & 0 deletions examples/tests/cycle_count/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Test `cycle_count`
====================

This tests the cycle counter capsule.
It will print the number of cycles required to toggle an LED.
36 changes: 36 additions & 0 deletions examples/tests/cycle_count/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <stdio.h>

#include <cycle_counter.h>
#include <led.h>
#include <tock.h>

int main(void) {
uint64_t cycles = 0;

int rc = cycle_counter_reset();
if (rc == RETURNCODE_ENOSUPPORT) {
printf("Cycle counter not available\n");
} else if (rc == RETURNCODE_ERESERVE) {
printf("Cycle counter claimed by another app\n");
} else if (rc != 0) {
printf("Cycle counter: other error: %d\n", rc);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
printf("Cycle counter: other error: %d\n", rc);
printf("Cycle counter: other error: %d (%s)\n", rc, tock_strerr(rc));

}

if (rc != 0) {
return 0;
}

cycle_counter_start();
led_toggle(0);
cycle_counter_stop();
cycle_counter_read(&cycles);
printf("cycles to toggle led first time: %lld\n", cycles);

cycle_counter_reset();
cycle_counter_start();
led_toggle(0);
cycle_counter_stop();
cycle_counter_read(&cycles);
printf("cycles to toggle led second time: %lld\n", cycles);
return 0;
}
29 changes: 29 additions & 0 deletions libtock/cycle_counter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "cycle_counter.h"

bool cycle_counter_exists(void) {
return driver_exists(DRIVER_NUM_CYCLE_COUNTER);
}

// Start the cycle counter
int cycle_counter_start(void) {
syscall_return_t rval = command(DRIVER_NUM_CYCLE_COUNTER, 1, 0, 0);
return tock_command_return_novalue_to_returncode(rval);
}

// Get the current cycle count
int cycle_counter_read(uint64_t* count) {
syscall_return_t rval = command(DRIVER_NUM_CYCLE_COUNTER, 2, 0, 0);
return tock_command_return_u64_to_returncode(rval, (uint64_t*) count);
}

// Reset the cycle counter
int cycle_counter_reset(void) {
syscall_return_t rval = command(DRIVER_NUM_CYCLE_COUNTER, 3, 0, 0);
return tock_command_return_novalue_to_returncode(rval);
}

// Stop the cycle counter
int cycle_counter_stop(void) {
syscall_return_t rval = command(DRIVER_NUM_CYCLE_COUNTER, 4, 0, 0);
return tock_command_return_novalue_to_returncode(rval);
}
19 changes: 19 additions & 0 deletions libtock/cycle_counter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include "tock.h"

#ifdef __cplusplus
extern "C" {
#endif

#define DRIVER_NUM_CYCLE_COUNTER 0x00090008

bool cycle_counter_exists(void);
int cycle_counter_start(void);
int cycle_counter_stop(void);
int cycle_counter_reset(void);
int cycle_counter_read(uint64_t *count);

#ifdef __cplusplus
}
#endif
15 changes: 15 additions & 0 deletions libtock/tock.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,21 @@ int tock_command_return_u32_to_returncode(syscall_return_t command_return, uint3
}
}

int tock_command_return_u64_to_returncode(syscall_return_t command_return, uint64_t* val) {
if (command_return.type == TOCK_SYSCALL_SUCCESS_U64) {
uint32_t upper = command_return.data[1];
uint32_t lower = command_return.data[0];
*val = ((uint64_t)upper << 32) | lower;
return RETURNCODE_SUCCESS;
} else if (command_return.type == TOCK_SYSCALL_FAILURE) {
return tock_status_to_returncode(command_return.data[0]);
} else {
// The remaining SyscallReturn variants must never happen if using this
// function. We return `EBADRVAL` to signal an unexpected return variant.
return RETURNCODE_EBADRVAL;
}
}

int tock_subscribe_return_to_returncode(subscribe_return_t subscribe_return) {
// If the subscribe was successful, easily return SUCCESS.
if (subscribe_return.success) {
Expand Down
7 changes: 7 additions & 0 deletions libtock/tock.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ int tock_command_return_novalue_to_returncode(syscall_return_t);
// variants.
int tock_command_return_u32_to_returncode(syscall_return_t, uint32_t*);

// Convert a `syscall_return_t` with two u32s to a `returncode_t`.
//
// This expects exactly two u32s to be returned (i.e. the only success case is
// `TOCK_SYSCALL_SUCCESS_U64`). Do not use with other expected SyscallReturn
// variants.
int tock_command_return_u64_to_returncode(syscall_return_t, uint64_t*);

// Convert a `subscribe_return_t` to a `returncode_t`.
int tock_subscribe_return_to_returncode(subscribe_return_t);

Expand Down
Loading