akaros/kern/arch/x86/msr.c
<<
>>
Prefs
   1/* Copyright (c) 2015 Google Inc
   2 * Davide Libenzi <dlibenzi@google.com>
   3 * See LICENSE for details.
   4 */
   5
   6#include <ros/common.h>
   7#include <compiler.h>
   8#include <kmalloc.h>
   9#include <kthread.h>
  10#include <string.h>
  11#include <stdio.h>
  12#include <assert.h>
  13#include <error.h>
  14#include <pmap.h>
  15#include <umem.h>
  16#include <smp.h>
  17#include <core_set.h>
  18#include <completion.h>
  19#include <arch/uaccess.h>
  20#include <arch/msr.h>
  21
  22struct smp_read_values {
  23        const struct msr_address *msra;
  24        struct msr_value *msrv;
  25        int err;
  26};
  27
  28struct smp_write_values {
  29        const struct msr_address *msra;
  30        const struct msr_value *msrv;
  31        int err;
  32};
  33
  34static void msr_smp_read(void *opaque)
  35{
  36        struct smp_read_values *srv = (struct smp_read_values *) opaque;
  37        int err, coreno = core_id();
  38        uint32_t addr;
  39        uint64_t value;
  40
  41        err = msr_get_core_address(coreno, srv->msra, &addr);
  42        if (err)
  43                goto errout;
  44        err = read_msr_safe(addr, &value);
  45        if (err)
  46                goto errout;
  47        err = msr_set_core_value(coreno, value, srv->msrv);
  48        if (err)
  49                goto errout;
  50
  51        return;
  52
  53errout:
  54        srv->err = err;
  55}
  56
  57int msr_cores_read(const struct core_set *cset, const struct msr_address *msra,
  58                   struct msr_value *msrv)
  59{
  60        int err;
  61        struct smp_read_values srv;
  62
  63        ZERO_DATA(srv);
  64        srv.msra = msra;
  65        srv.msrv = msrv;
  66        srv.err = 0;
  67        smp_do_in_cores(cset, msr_smp_read, &srv);
  68
  69        return srv.err;
  70}
  71
  72int msr_core_read(unsigned int coreno, uint32_t addr, uint64_t *value)
  73{
  74        int err;
  75        struct core_set cset;
  76        struct msr_address msra;
  77        struct msr_value msrv;
  78
  79        core_set_init(&cset);
  80        core_set_setcpu(&cset, coreno);
  81        msr_set_address(&msra, addr);
  82        msr_set_values(&msrv, NULL, 0);
  83        err = msr_cores_read(&cset, &msra, &msrv);
  84        *value = msrv.value;
  85
  86        return err;
  87}
  88
  89static void msr_smp_write(void *opaque)
  90{
  91        struct smp_write_values *swv = (struct smp_write_values *) opaque;
  92        int err, coreno = core_id();
  93        uint32_t addr;
  94        uint64_t value;
  95
  96        err = msr_get_core_address(coreno, swv->msra, &addr);
  97        if (err)
  98                goto errout;
  99        err = msr_get_core_value(coreno, swv->msrv, &value);
 100        if (err)
 101                goto errout;
 102        err = write_msr_safe(addr, value);
 103        if (err)
 104                goto errout;
 105
 106        return;
 107
 108errout:
 109        swv->err = err;
 110}
 111
 112int msr_cores_write(const struct core_set *cset, const struct msr_address *msra,
 113                    const struct msr_value *msrv)
 114{
 115        struct smp_write_values swv;
 116
 117        ZERO_DATA(swv);
 118        swv.msra = msra;
 119        swv.msrv = msrv;
 120        swv.err = 0;
 121        smp_do_in_cores(cset, msr_smp_write, &swv);
 122
 123        return swv.err;
 124}
 125
 126int msr_core_write(unsigned int coreno, uint32_t addr, uint64_t value)
 127{
 128        struct core_set cset;
 129        struct msr_address msra;
 130        struct msr_value msrv;
 131
 132        core_set_init(&cset);
 133        core_set_setcpu(&cset, coreno);
 134        msr_set_address(&msra, addr);
 135        msr_set_value(&msrv, value);
 136
 137        return msr_cores_write(&cset, &msra, &msrv);
 138}
 139