akaros/kern/arch/x86/msr.h
<<
>>
Prefs
   1/* Copyright (c) 2015 Google Inc
   2 * Davide Libenzi <dlibenzi@google.com>
   3 * See LICENSE for details.
   4 */
   5
   6#pragma once
   7
   8#include <sys/types.h>
   9#include <ros/errno.h>
  10#include <stdio.h>
  11#include <string.h>
  12#include <core_set.h>
  13
  14/* The msr_address and msr_value structures allow to specify either a single
  15 * address/value for all cores, or dedicated ones for every core.
  16 * This allow a single logical call to msr_cores_read()/msr_cores_write() APIs,
  17 * to read/write MSRs at different addresses and using different values.
  18 */
  19struct msr_address {
  20        uint32_t addr;
  21        const uint32_t *addresses;
  22        size_t num_addresses;
  23};
  24
  25struct msr_value {
  26        uint64_t value;
  27        uint64_t *values;
  28        size_t num_values;
  29};
  30
  31int msr_cores_read(const struct core_set *cset, const struct msr_address *msra,
  32                   struct msr_value *msrv);
  33int msr_core_read(unsigned int core, uint32_t addr, uint64_t *value);
  34int msr_cores_write(const struct core_set *cset, const struct msr_address *msra,
  35                    const struct msr_value *msrv);
  36int msr_core_write(unsigned int core, uint32_t addr, uint64_t value);
  37
  38static inline void msr_set_address(struct msr_address *msra, uint32_t addr)
  39{
  40        ZERO_DATA(*msra);
  41        msra->addr = addr;
  42}
  43
  44static inline void msr_set_addresses(struct msr_address *msra,
  45                                     const uint32_t *addresses,
  46                                     size_t num_addresses)
  47{
  48        ZERO_DATA(*msra);
  49        msra->addresses = addresses;
  50        msra->num_addresses = num_addresses;
  51}
  52
  53static inline int msr_get_core_address(unsigned int coreno,
  54                                       const struct msr_address *msra,
  55                                       uint32_t *paddr)
  56{
  57        if (msra->addresses != NULL) {
  58                if (coreno >= (unsigned int) msra->num_addresses)
  59                        return -ERANGE;
  60
  61                *paddr = msra->addresses[coreno];
  62        } else {
  63                *paddr = msra->addr;
  64        }
  65
  66        return 0;
  67}
  68
  69static inline void msr_set_value(struct msr_value *msrv, uint64_t value)
  70{
  71        ZERO_DATA(*msrv);
  72        msrv->value = value;
  73}
  74
  75static inline void msr_set_values(struct msr_value *msrv,
  76                                  const uint64_t *values, size_t num_values)
  77{
  78        ZERO_DATA(*msrv);
  79
  80        /* Avoid supporting two APIs, one for setting const values, and one for
  81         * setting the non const ones.
  82         */
  83        msrv->values = (uint64_t *) values;
  84        msrv->num_values = num_values;
  85}
  86
  87static inline int msr_set_core_value(unsigned int coreno, uint64_t value,
  88                                     struct msr_value *msrv)
  89{
  90        if (msrv->values != NULL) {
  91                if (coreno >= (unsigned int) msrv->num_values)
  92                        return -ERANGE;
  93
  94                msrv->values[coreno] = value;
  95        } else {
  96                msrv->value = value;
  97        }
  98
  99        return 0;
 100}
 101
 102static inline int msr_get_core_value(unsigned int coreno,
 103                                     const struct msr_value *msrv,
 104                                     uint64_t *pvalue)
 105{
 106        if (msrv->values != NULL) {
 107                if (coreno >= (unsigned int) msrv->num_values)
 108                        return -ERANGE;
 109
 110                *pvalue = msrv->values[coreno];
 111        } else {
 112                *pvalue = msrv->value;
 113        }
 114
 115        return 0;
 116}
 117