arch: x86: Rename MSR-handling functions to conform to convention

Rename _MsrRead() and _MsrWrite() to _x86_msr_read() and
_x86_msr_write() respectively.

Given that these functions are essentially implemented in assembly.
make them static inline.  They can be inlined by the compiler quite
well, most of the time incurring in space savings due to better
handling of the cobbled registers.

Also simplifies the inline assembly, using constraints instead of
moving registers ourselves.  Should shave off a few bytes from code
using these functions.

Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
This commit is contained in:
Leandro Pereira 2018-05-22 12:11:44 -07:00 committed by Anas Nashif
commit d4221f9a71
4 changed files with 42 additions and 85 deletions

View file

@ -15,7 +15,6 @@ zephyr_library_sources(
excstub.S
intstub.S
irq_manage.c
msr.c
swap.S
sys_fatal_error_handler.c
thread.c

View file

@ -1,77 +0,0 @@
/*
* Copyright (c) 2011-2014 Wind River Systems, Inc.
* Copyright (c) 2015 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file Utilities to read/write the Model Specific Registers (MSRs)
*/
#include <zephyr.h>
/**
*
* @brief Write to a model specific register (MSR)
*
* This function is used to write to an MSR.
*
* The definitions of the so-called "Architectural MSRs" are contained
* in kernel_structs.h and have the format: IA32_XXX_MSR
*
* INTERNAL
* 1) The 'wrmsr' instruction was introduced in the Pentium processor; executing
* this instruction on an earlier IA-32 processor will result in an invalid
* opcode exception.
* 2) The 'wrmsr' uses the ECX, EDX, and EAX registers which matches the set of
* volatile registers!
*
* @return N/A
*/
void _MsrWrite(unsigned int msr, u64_t msr_data)
{
__asm__ volatile (
"movl %[msr], %%ecx\n\t"
"movl %[data_lo], %%eax\n\t"
"movl %[data_hi], %%edx\n\t"
"wrmsr"
:
: [msr] "m" (msr),
[data_lo] "rm" ((u32_t)(msr_data & 0xFFFFFFFF)),
[data_hi] "rm" ((u32_t)(msr_data >> 32))
: "eax", "ecx", "edx");
}
/**
*
* @brief Read from a model specific register (MSR)
*
* This function is used to read from an MSR.
*
* The definitions of the so-called "Architectural MSRs" are contained
* in kernel_structs.h and have the format: IA32_XXX_MSR
*
* INTERNAL
* 1) The 'rdmsr' instruction was introduced in the Pentium processor; executing
* this instruction on an earlier IA-32 processor will result in an invalid
* opcode exception.
* 2) The 'rdmsr' uses the ECX, EDX, and EAX registers which matches the set of
* volatile registers!
*
* @return N/A
*/
u64_t _MsrRead(unsigned int msr)
{
u64_t ret;
__asm__ volatile (
"movl %[msr], %%ecx\n\t"
"rdmsr"
: "=A" (ret)
: [msr] "rm" (msr)
: "ecx");
return ret;
}

View file

@ -97,8 +97,8 @@
#define IV_INTEL_RESERVED_END 31
/*
* Model specific register (MSR) definitions. Use the _MsrRead() and
* _MsrWrite() primitives to read/write the MSRs. Only the so-called
* Model specific register (MSR) definitions. Use the _x86_msr_read() and
* _x86_msr_write() primitives to read/write the MSRs. Only the so-called
* "Architectural MSRs" are listed, i.e. the subset of MSRs and associated
* bit fields which will not change on future processor generations.
*/

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2016 Wind River Systems, Inc.
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -66,20 +67,54 @@ _set_thread_return_value(struct k_thread *thread, unsigned int value)
extern void k_cpu_atomic_idle(unsigned int imask);
extern void _MsrWrite(unsigned int msr, u64_t msrData);
extern u64_t _MsrRead(unsigned int msr);
/**
* @brief Write to a model specific register (MSR)
*
* This function is used to write to an MSR.
*
* The definitions of the so-called "Architectural MSRs" are contained
* in kernel_structs.h and have the format: IA32_XXX_MSR
*
* @return N/A
*/
static inline void _x86_msr_write(unsigned int msr, u64_t data)
{
u32_t high = data >> 32;
u32_t low = data & 0xFFFFFFFF;
__asm__ volatile ("wrmsr" : : "c"(msr), "a"(low), "d"(high));
}
/**
* @brief Read from a model specific register (MSR)
*
* This function is used to read from an MSR.
*
* The definitions of the so-called "Architectural MSRs" are contained
* in kernel_structs.h and have the format: IA32_XXX_MSR
*
* @return N/A
*/
static inline u64_t _x86_msr_read(unsigned int msr)
{
u64_t ret;
__asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr));
return ret;
}
#ifdef CONFIG_JAILHOUSE_X2APIC
#define MSR_X2APIC_BASE 0x00000800
static inline u32_t read_x2apic(unsigned int reg)
{
return _MsrRead(MSR_X2APIC_BASE + reg);
return _x86_msr_read(MSR_X2APIC_BASE + reg);
}
static inline void write_x2apic(unsigned int reg, u32_t val)
{
_MsrWrite(MSR_X2APIC_BASE + reg, val);
_x86_msr_write(MSR_X2APIC_BASE + reg, val);
}
#endif