blob: 6367745b8cc63788bec8a1e579b06a2c7373cc24 [file] [log] [blame]
/* Copyright (c) 2015 Google Inc
* Davide Libenzi <dlibenzi@google.com>
* See LICENSE for details.
*/
#pragma once
#include <sys/types.h>
#include <ros/errno.h>
#include <stdio.h>
#include <string.h>
#include <core_set.h>
/* The msr_address and msr_value structures allow to specify either a single
* address/value for all cores, or dedicated ones for every core.
* This allow a single logical call to msr_cores_read()/msr_cores_write() APIs,
* to read/write MSRs at different addresses and using different values.
*/
struct msr_address {
uint32_t addr;
const uint32_t *addresses;
size_t num_addresses;
};
struct msr_value {
uint64_t value;
uint64_t *values;
size_t num_values;
};
int msr_cores_read(const struct core_set *cset, const struct msr_address *msra,
struct msr_value *msrv);
int msr_core_read(unsigned int core, uint32_t addr, uint64_t *value);
int msr_cores_write(const struct core_set *cset, const struct msr_address *msra,
const struct msr_value *msrv);
int msr_core_write(unsigned int core, uint32_t addr, uint64_t value);
static inline void msr_set_address(struct msr_address *msra, uint32_t addr)
{
ZERO_DATA(*msra);
msra->addr = addr;
}
static inline void msr_set_addresses(struct msr_address *msra,
const uint32_t *addresses,
size_t num_addresses)
{
ZERO_DATA(*msra);
msra->addresses = addresses;
msra->num_addresses = num_addresses;
}
static inline int msr_get_core_address(unsigned int coreno,
const struct msr_address *msra,
uint32_t *paddr)
{
if (msra->addresses != NULL) {
if (coreno >= (unsigned int) msra->num_addresses)
return -ERANGE;
*paddr = msra->addresses[coreno];
} else {
*paddr = msra->addr;
}
return 0;
}
static inline void msr_set_value(struct msr_value *msrv, uint64_t value)
{
ZERO_DATA(*msrv);
msrv->value = value;
}
static inline void msr_set_values(struct msr_value *msrv,
const uint64_t *values, size_t num_values)
{
ZERO_DATA(*msrv);
/* Avoid supporting two APIs, one for setting const values, and one for
* setting the non const ones.
*/
msrv->values = (uint64_t *) values;
msrv->num_values = num_values;
}
static inline int msr_set_core_value(unsigned int coreno, uint64_t value,
struct msr_value *msrv)
{
if (msrv->values != NULL) {
if (coreno >= (unsigned int) msrv->num_values)
return -ERANGE;
msrv->values[coreno] = value;
} else {
msrv->value = value;
}
return 0;
}
static inline int msr_get_core_value(unsigned int coreno,
const struct msr_value *msrv,
uint64_t *pvalue)
{
if (msrv->values != NULL) {
if (coreno >= (unsigned int) msrv->num_values)
return -ERANGE;
*pvalue = msrv->values[coreno];
} else {
*pvalue = msrv->value;
}
return 0;
}