Add rdmsr(2) and wrmsr(2).

This commit is contained in:
Jonas 'Sortie' Termansen 2013-09-14 20:05:17 +02:00
parent 1f72c1637c
commit af23f7ad5e
10 changed files with 194 additions and 48 deletions

View File

@ -150,6 +150,8 @@
#define SYSCALL_GETUMASK 126
#define SYSCALL_FSTATVFS 127
#define SYSCALL_FSTATVFSAT 128
#define SYSCALL_MAX_NUM 129 /* index of highest constant + 1 */
#define SYSCALL_RDMSR 129
#define SYSCALL_WRMSR 130
#define SYSCALL_MAX_NUM 131 /* index of highest constant + 1 */
#endif

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
This file is part of Sortix.
@ -94,9 +94,13 @@
#include "uart.h"
#include "vga.h"
#include "vgatextbuffer.h"
#if defined(__i386__) || defined(__x86_64__)
#include "x86-family/cmos.h"
#include "x86-family/float.h"
#include "x86-family/gdt.h"
#include "x86-family/x86-family.h"
#endif
// Keep the stack size aligned with $CPU/base.s
const size_t STACK_SIZE = 64*1024;
@ -408,6 +412,9 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo)
// Stage 2. Transition to Multithreaded Environment
//
// Initialize CPU system calls.
CPU::Init();
// Initialize the clocks.
Time::Init();

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
This file is part of Sortix.
@ -22,9 +22,14 @@
*******************************************************************************/
#include <errno.h>
#include <msr.h>
#include <stdint.h>
#include <sortix/kernel/kernel.h>
#include <sortix/kernel/syscall.h>
#include "gdt.h"
namespace Sortix {
namespace CPU {
@ -107,5 +112,61 @@ void ShutDown()
Reboot();
}
static uint64_t sys_rdmsr(uint32_t msrid)
{
switch ( msrid )
{
case MSRID_FSBASE:
#if defined(__i386__)
return GDT::GetFSBase();
#elif defined(__x86_64__)
return rdmsr(msrid);
#endif
case MSRID_GSBASE:
#if defined(__i386__)
return GDT::GetGSBase();
#elif defined(__x86_64__)
return rdmsr(msrid);
#endif
default:
return errno = EPERM, UINT64_MAX;
};
}
static uint64_t sys_wrmsr(uint32_t msrid, uint64_t value)
{
switch ( msrid )
{
case MSRID_FSBASE:
#if defined(__i386__)
if ( UINT32_MAX < value )
return errno = EINVAL, UINT64_MAX;
return GDT::SetFSBase((uint32_t) value), value;
#elif defined(__x86_64__)
if ( value >> 48 != 0x0000 && value >> 48 != 0xFFFF )
return errno = EINVAL, UINT64_MAX;
return wrmsr(msrid, value);
#endif
case MSRID_GSBASE:
#if defined(__i386__)
if ( UINT32_MAX < value )
return errno = EINVAL, UINT64_MAX;
return GDT::SetGSBase((uint32_t) value), value;
#elif defined(__x86_64__)
if ( value >> 48 != 0x0000 && value >> 48 != 0xFFFF )
return errno = EINVAL, UINT64_MAX;
return wrmsr(msrid, value);
#endif
default:
return errno = EPERM, UINT64_MAX;
};
}
void Init()
{
Syscall::Register(SYSCALL_RDMSR, (void*) sys_rdmsr);
Syscall::Register(SYSCALL_WRMSR, (void*) sys_wrmsr);
}
} // namespace CPU
} // namespace Sortix

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2014.
This file is part of Sortix.
@ -22,51 +22,17 @@
*******************************************************************************/
#ifndef SORTIX_X86_FAMILY_H
#define SORTIX_X86_FAMILY_H
#ifndef SORTIX_X86_FAMILY_X86_FAMILY_H
#define SORTIX_X86_FAMILY_X86_FAMILY_H
#include <stddef.h>
#include <stdint.h>
#include <sortix/kernel/decl.h>
namespace Sortix {
namespace CPU {
void OutPortB(uint16_t port, uint8_t value);
void OutPortW(uint16_t port, uint16_t value);
void OutPortL(uint16_t port, uint32_t value);
uint8_t InPortB(uint16_t port);
uint16_t InPortW(uint16_t port);
uint32_t InPortL(uint16_t port);
void Reboot();
void ShutDown();
void Init();
} // namespace CPU
} // namespace Sortix
namespace Sortix {
const size_t FLAGS_CARRY = 1 << 0; // 0x000001
const size_t FLAGS_RESERVED1 = 1 << 1; // 0x000002, read as one
const size_t FLAGS_PARITY = 1 << 2; // 0x000004
const size_t FLAGS_RESERVED2 = 1 << 3; // 0x000008
const size_t FLAGS_AUX = 1 << 4; // 0x000010
const size_t FLAGS_RESERVED3 = 1 << 5; // 0x000020
const size_t FLAGS_ZERO = 1 << 6; // 0x000040
const size_t FLAGS_SIGN = 1 << 7; // 0x000080
const size_t FLAGS_TRAP = 1 << 8; // 0x000100
const size_t FLAGS_INTERRUPT = 1 << 9; // 0x000200
const size_t FLAGS_DIRECTION = 1 << 10; // 0x000400
const size_t FLAGS_OVERFLOW = 1 << 11; // 0x000800
const size_t FLAGS_IOPRIVLEVEL = 1 << 12) | 1 << 13;
const size_t FLAGS_NESTEDTASK = 1 << 14; // 0x004000
const size_t FLAGS_RESERVED4 = 1 << 15; // 0x008000
const size_t FLAGS_RESUME = 1 << 16; // 0x010000
const size_t FLAGS_VIRTUAL8086 = 1 << 17; // 0x020000
const size_t FLAGS_ALIGNCHECK = 1 << 18; // 0x040000
const size_t FLAGS_VIRTINTR = 1 << 19; // 0x080000
const size_t FLAGS_VIRTINTRPEND = 1 << 20; // 0x100000
const size_t FLAGS_ID = 1 << 21; // 0x200000
} // namespace Sortix
#endif

View File

@ -302,6 +302,8 @@ libgen/basename.o \
libgen/dirname.o \
locale/localeconv.o \
locale/setlocale.o \
msr/rdmsr.o \
msr/wrmsr.o \
netdb/endhostent.o \
netdb/endnetent.o \
netdb/endprotoent.o \

View File

@ -38,7 +38,7 @@ __BEGIN_DECLS
#define MSRID_GSBASE __UINT32_C(0xC0000101)
__attribute__((unused))
static __inline uint64_t rdmsr(uint32_t msrid)
static __inline uint64_t rdmsr_instruction(uint32_t msrid)
{
uint32_t low;
uint32_t high;
@ -47,7 +47,7 @@ static __inline uint64_t rdmsr(uint32_t msrid)
}
__attribute__((unused))
static __inline uint64_t wrmsr(uint32_t msrid, uint64_t value)
static __inline uint64_t wrmsr_instruction(uint32_t msrid, uint64_t value)
{
uint32_t low = value >> 0 & 0xFFFFFFFF;
uint32_t high = value >> 32 & 0xFFFFFFFF;;
@ -55,6 +55,27 @@ static __inline uint64_t wrmsr(uint32_t msrid, uint64_t value)
return value;
}
#if __STDC_HOSTED__
uint64_t rdmsr(uint32_t msrid);
uint64_t wrmsr(uint32_t msrid, uint64_t value);
#else
__attribute__((unused))
static __inline uint64_t rdmsr(uint32_t msrid)
{
return rdmsr_instruction(msrid);
}
__attribute__((unused))
static __inline uint64_t wrmsr(uint32_t msrid, uint64_t value)
{
return wrmsr_instruction(msrid, value);
}
#endif
__attribute__((unused))
static __inline void rdmsr_split(uint32_t msrid, uint32_t* low, uint32_t* high)
{

39
libc/msr/rdmsr.cpp Normal file
View File

@ -0,0 +1,39 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013
This file is part of the Sortix C Library.
The Sortix C Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
The Sortix C Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
msr/rdmsr.cpp
Reads a model specific register.
*******************************************************************************/
#include <sys/syscall.h>
#include <stdint.h>
#include <msr.h>
#if defined(__i386__) || defined(__x86_64__)
DEFN_SYSCALL1(uint64_t, sys_rdmsr, SYSCALL_RDMSR, uint32_t);
extern "C" uint64_t rdmsr(uint32_t msrid)
{
return sys_rdmsr(msrid);
}
#endif

39
libc/msr/wrmsr.cpp Normal file
View File

@ -0,0 +1,39 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013
This file is part of the Sortix C Library.
The Sortix C Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
The Sortix C Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
msr/rdmsr.cpp
Sets a model specific register.
*******************************************************************************/
#include <sys/syscall.h>
#include <stdint.h>
#include <msr.h>
#if defined(__i386__) || defined(__x86_64__)
DEFN_SYSCALL2(uint64_t, sys_wrmsr, SYSCALL_WRMSR, uint32_t, uint64_t);
extern "C" uint64_t wrmsr(uint32_t msrid, uint64_t value)
{
return sys_wrmsr(msrid, value);
}
#endif

View File

@ -41,8 +41,13 @@ __call_tfork_with_regs:
# of each register in the child. Since we create an identical copy, we
# simply set each member of the structure to our own state. Note that since
# the stack goes downwards, we create it in the reverse order.
pushq $0 # gsbase
pushq $0 # fsbase
movl $MSRID_GSBASE, %edi
call rdmsr
pushq %rax
movl $MSRID_FSBASE, %edi
call rdmsr
pushq %rax
movq -8(%rbp), %rdi
pushfq
pushq %r15
pushq %r14

View File

@ -37,8 +37,12 @@ __call_tfork_with_regs:
# of each register in the child. Since we create an identical copy, we
# simply set each member of the structure to our own state. Note that since
# the stack goes downwards, we create it in the reverse order.
pushl $0 # gsbase
pushl $0 # fsbase
pushl $MSRID_GSBASE
call rdmsr
movl %eax, (%esp)
pushl $MSRID_FSBASE
call rdmsr
movl %eax, (%esp)
pushfl
pushl %ebp
pushl %esp