mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 00:42:44 +00:00 
			
		
		
		
	 04a912f68f
			
		
	
	
		04a912f68f
		
	
	
	
	
		
			
			When retrieving and setting x86 MSRs two registers are required. The existing setter and getter for the MSR class made this implementation detail visible to the caller. This changes the setter and getter to use u64 instead.
		
			
				
	
	
		
			50 lines
		
	
	
	
		
			870 B
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			50 lines
		
	
	
	
		
			870 B
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <AK/Types.h>
 | |
| 
 | |
| #include <Kernel/Arch/x86/CPUID.h>
 | |
| 
 | |
| namespace Kernel {
 | |
| 
 | |
| class MSR {
 | |
|     uint32_t m_msr;
 | |
| 
 | |
| public:
 | |
|     static bool have()
 | |
|     {
 | |
|         CPUID id(1);
 | |
|         return (id.edx() & (1 << 5)) != 0;
 | |
|     }
 | |
| 
 | |
|     MSR(const MSR&) = delete;
 | |
|     MSR& operator=(const MSR&) = delete;
 | |
| 
 | |
|     MSR(uint32_t msr)
 | |
|         : m_msr(msr)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] u64 get()
 | |
|     {
 | |
|         u32 low, high;
 | |
|         asm volatile("rdmsr"
 | |
|                      : "=a"(low), "=d"(high)
 | |
|                      : "c"(m_msr));
 | |
|         return ((u64)high << 32) | low;
 | |
|     }
 | |
| 
 | |
|     void set(u64 value)
 | |
|     {
 | |
|         u32 low = value & 0xffffffff;
 | |
|         u32 high = value >> 32;
 | |
|         asm volatile("wrmsr" ::"a"(low), "d"(high), "c"(m_msr));
 | |
|     }
 | |
| };
 | |
| 
 | |
| }
 |