Add rdmsr(2) and wrmsr(2).
This commit is contained in:
parent
1f72c1637c
commit
af23f7ad5e
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue