mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 09:02:43 +00:00 
			
		
		
		
	Kernel: Consolidate features into CPUFeature enum
This allows us to consolidate printing out all the CPU features into one log statement. Also expose them in /proc/cpuinfo
This commit is contained in:
		
							parent
							
								
									e373e5f007
								
							
						
					
					
						commit
						9b4e6f6a23
					
				
					 9 changed files with 197 additions and 145 deletions
				
			
		|  | @ -26,6 +26,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <AK/Assertions.h> | #include <AK/Assertions.h> | ||||||
| #include <AK/String.h> | #include <AK/String.h> | ||||||
|  | #include <AK/StringBuilder.h> | ||||||
| #include <AK/Types.h> | #include <AK/Types.h> | ||||||
| #include <Kernel/Arch/i386/CPU.h> | #include <Kernel/Arch/i386/CPU.h> | ||||||
| #include <Kernel/Arch/i386/ProcessorInfo.h> | #include <Kernel/Arch/i386/ProcessorInfo.h> | ||||||
|  | @ -633,7 +634,7 @@ void exit_trap(TrapFrame* trap) | ||||||
|     return Processor::current().exit_trap(*trap); |     return Processor::current().exit_trap(*trap); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void sse_init() | static void sse_init() | ||||||
| { | { | ||||||
|     asm volatile( |     asm volatile( | ||||||
|         "mov %cr0, %eax\n" |         "mov %cr0, %eax\n" | ||||||
|  | @ -645,122 +646,6 @@ void sse_init() | ||||||
|         "mov %eax, %cr4\n"); |         "mov %eax, %cr4\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool g_cpu_supports_nx; |  | ||||||
| bool g_cpu_supports_pae; |  | ||||||
| bool g_cpu_supports_pge; |  | ||||||
| bool g_cpu_supports_rdrand; |  | ||||||
| bool g_cpu_supports_rdseed; |  | ||||||
| bool g_cpu_supports_smap; |  | ||||||
| bool g_cpu_supports_smep; |  | ||||||
| bool g_cpu_supports_sse; |  | ||||||
| bool g_cpu_supports_tsc; |  | ||||||
| bool g_cpu_supports_umip; |  | ||||||
| 
 |  | ||||||
| void cpu_detect() |  | ||||||
| { |  | ||||||
|     CPUID processor_info(0x1); |  | ||||||
|     g_cpu_supports_pae = (processor_info.edx() & (1 << 6)); |  | ||||||
|     g_cpu_supports_pge = (processor_info.edx() & (1 << 13)); |  | ||||||
|     g_cpu_supports_sse = (processor_info.edx() & (1 << 25)); |  | ||||||
|     g_cpu_supports_tsc = (processor_info.edx() & (1 << 4)); |  | ||||||
|     g_cpu_supports_rdrand = (processor_info.ecx() & (1 << 30)); |  | ||||||
| 
 |  | ||||||
|     CPUID extended_processor_info(0x80000001); |  | ||||||
|     g_cpu_supports_nx = (extended_processor_info.edx() & (1 << 20)); |  | ||||||
| 
 |  | ||||||
|     CPUID extended_features(0x7); |  | ||||||
|     g_cpu_supports_smap = (extended_features.ebx() & (1 << 20)); |  | ||||||
|     g_cpu_supports_smep = (extended_features.ebx() & (1 << 7)); |  | ||||||
|     g_cpu_supports_umip = (extended_features.ecx() & (1 << 2)); |  | ||||||
|     g_cpu_supports_rdseed = (extended_features.ebx() & (1 << 18)); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void cpu_setup(u32 cpu) |  | ||||||
| { |  | ||||||
|     if (cpu == 0) |  | ||||||
|         cpu_detect(); |  | ||||||
| 
 |  | ||||||
|     if (g_cpu_supports_sse) { |  | ||||||
|         sse_init(); |  | ||||||
|         klog() << "x86: SSE support enabled"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     asm volatile( |  | ||||||
|         "movl %%cr0, %%eax\n" |  | ||||||
|         "orl $0x00010000, %%eax\n" |  | ||||||
|         "movl %%eax, %%cr0\n" :: |  | ||||||
|             : "%eax", "memory"); |  | ||||||
|     klog() << "x86: WP support enabled"; |  | ||||||
| 
 |  | ||||||
|     if (g_cpu_supports_pge) { |  | ||||||
|         // Turn on CR4.PGE so the CPU will respect the G bit in page tables.
 |  | ||||||
|         asm volatile( |  | ||||||
|             "mov %cr4, %eax\n" |  | ||||||
|             "orl $0x80, %eax\n" |  | ||||||
|             "mov %eax, %cr4\n"); |  | ||||||
|         klog() << "x86: PGE support enabled"; |  | ||||||
|     } else { |  | ||||||
|         klog() << "x86: PGE support not detected"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (g_cpu_supports_nx) { |  | ||||||
|         // Turn on IA32_EFER.NXE
 |  | ||||||
|         asm volatile( |  | ||||||
|             "movl $0xc0000080, %ecx\n" |  | ||||||
|             "rdmsr\n" |  | ||||||
|             "orl $0x800, %eax\n" |  | ||||||
|             "wrmsr\n"); |  | ||||||
|         klog() << "x86: NX support enabled"; |  | ||||||
|     } else { |  | ||||||
|         klog() << "x86: NX support not detected"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (g_cpu_supports_smep) { |  | ||||||
|         // Turn on CR4.SMEP
 |  | ||||||
|         asm volatile( |  | ||||||
|             "mov %cr4, %eax\n" |  | ||||||
|             "orl $0x100000, %eax\n" |  | ||||||
|             "mov %eax, %cr4\n"); |  | ||||||
|         klog() << "x86: SMEP support enabled"; |  | ||||||
|     } else { |  | ||||||
|         klog() << "x86: SMEP support not detected"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (g_cpu_supports_smap) { |  | ||||||
|         // Turn on CR4.SMAP
 |  | ||||||
|         klog() << "x86: Enabling SMAP"; |  | ||||||
|         asm volatile( |  | ||||||
|             "mov %cr4, %eax\n" |  | ||||||
|             "orl $0x200000, %eax\n" |  | ||||||
|             "mov %eax, %cr4\n"); |  | ||||||
|         klog() << "x86: SMAP support enabled"; |  | ||||||
|     } else { |  | ||||||
|         klog() << "x86: SMAP support not detected"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (g_cpu_supports_umip) { |  | ||||||
|         asm volatile( |  | ||||||
|             "mov %cr4, %eax\n" |  | ||||||
|             "orl $0x800, %eax\n" |  | ||||||
|             "mov %eax, %cr4\n"); |  | ||||||
|         klog() << "x86: UMIP support enabled"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (g_cpu_supports_tsc) { |  | ||||||
|         asm volatile( |  | ||||||
|             "mov %cr4, %eax\n" |  | ||||||
|             "orl $0x4, %eax\n" |  | ||||||
|             "mov %eax, %cr4\n"); |  | ||||||
|         klog() << "x86: RDTSC support restricted"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (g_cpu_supports_rdrand) { |  | ||||||
|         klog() << "x86: Using RDRAND for good randomness"; |  | ||||||
|     } else { |  | ||||||
|         klog() << "x86: No RDRAND support detected, randomness will be poor"; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| u32 read_cr0() | u32 read_cr0() | ||||||
| { | { | ||||||
|     u32 cr0; |     u32 cr0; | ||||||
|  | @ -822,6 +707,156 @@ Processor& Processor::by_id(u32 cpu) | ||||||
|     return *procs[cpu]; |     return *procs[cpu]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | void Processor::cpu_detect() | ||||||
|  | { | ||||||
|  |     // NOTE: This is called during Processor::early_initialize, we cannot
 | ||||||
|  |     //       safely log at this point because we don't have kmalloc
 | ||||||
|  |     //       initialized yet!
 | ||||||
|  |     auto set_feature = | ||||||
|  |         [&](CPUFeature f) { | ||||||
|  |             m_features = static_cast<CPUFeature>(static_cast<u32>(m_features) | static_cast<u32>(f)); | ||||||
|  |         }; | ||||||
|  |     m_features = static_cast<CPUFeature>(0); | ||||||
|  | 
 | ||||||
|  |     CPUID processor_info(0x1); | ||||||
|  |     if (processor_info.edx() & (1 << 6)) | ||||||
|  |         set_feature(CPUFeature::PAE); | ||||||
|  |     if (processor_info.edx() & (1 << 13)) | ||||||
|  |         set_feature(CPUFeature::PGE); | ||||||
|  |     if (processor_info.edx() & (1 << 25)) | ||||||
|  |         set_feature(CPUFeature::SSE); | ||||||
|  |     if (processor_info.edx() & (1 << 4)) | ||||||
|  |         set_feature(CPUFeature::TSC); | ||||||
|  |     if (processor_info.ecx() & (1 << 30)) | ||||||
|  |         set_feature(CPUFeature::RDRAND); | ||||||
|  | 
 | ||||||
|  |     CPUID extended_processor_info(0x80000001); | ||||||
|  |     if (extended_processor_info.edx() & (1 << 20)) | ||||||
|  |         set_feature(CPUFeature::NX); | ||||||
|  | 
 | ||||||
|  |     CPUID extended_features(0x7); | ||||||
|  |     if (extended_features.ebx() & (1 << 20)) | ||||||
|  |         set_feature(CPUFeature::SMAP); | ||||||
|  |     if (extended_features.ebx() & (1 << 7)) | ||||||
|  |         set_feature(CPUFeature::SMEP); | ||||||
|  |     if (extended_features.ecx() & (1 << 2)) | ||||||
|  |         set_feature(CPUFeature::UMIP); | ||||||
|  |     if (extended_features.ebx() & (1 << 18)) | ||||||
|  |         set_feature(CPUFeature::RDSEED); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Processor::cpu_setup() | ||||||
|  | { | ||||||
|  |     // NOTE: This is called during Processor::early_initialize, we cannot
 | ||||||
|  |     //       safely log at this point because we don't have kmalloc
 | ||||||
|  |     //       initialized yet!
 | ||||||
|  |     cpu_detect(); | ||||||
|  | 
 | ||||||
|  |     if (has_feature(CPUFeature::SSE)) | ||||||
|  |         sse_init(); | ||||||
|  | 
 | ||||||
|  |     asm volatile( | ||||||
|  |         "movl %%cr0, %%eax\n" | ||||||
|  |         "orl $0x00010000, %%eax\n" | ||||||
|  |         "movl %%eax, %%cr0\n" :: | ||||||
|  |             : "%eax", "memory"); | ||||||
|  | 
 | ||||||
|  |     if (has_feature(CPUFeature::PGE)) { | ||||||
|  |         // Turn on CR4.PGE so the CPU will respect the G bit in page tables.
 | ||||||
|  |         asm volatile( | ||||||
|  |             "mov %cr4, %eax\n" | ||||||
|  |             "orl $0x80, %eax\n" | ||||||
|  |             "mov %eax, %cr4\n"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (has_feature(CPUFeature::NX)) { | ||||||
|  |         // Turn on IA32_EFER.NXE
 | ||||||
|  |         asm volatile( | ||||||
|  |             "movl $0xc0000080, %ecx\n" | ||||||
|  |             "rdmsr\n" | ||||||
|  |             "orl $0x800, %eax\n" | ||||||
|  |             "wrmsr\n"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (has_feature(CPUFeature::SMEP)) { | ||||||
|  |         // Turn on CR4.SMEP
 | ||||||
|  |         asm volatile( | ||||||
|  |             "mov %cr4, %eax\n" | ||||||
|  |             "orl $0x100000, %eax\n" | ||||||
|  |             "mov %eax, %cr4\n"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (has_feature(CPUFeature::SMAP)) { | ||||||
|  |         // Turn on CR4.SMAP
 | ||||||
|  |         asm volatile( | ||||||
|  |             "mov %cr4, %eax\n" | ||||||
|  |             "orl $0x200000, %eax\n" | ||||||
|  |             "mov %eax, %cr4\n"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (has_feature(CPUFeature::UMIP)) { | ||||||
|  |         asm volatile( | ||||||
|  |             "mov %cr4, %eax\n" | ||||||
|  |             "orl $0x800, %eax\n" | ||||||
|  |             "mov %eax, %cr4\n"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (has_feature(CPUFeature::TSC)) { | ||||||
|  |         asm volatile( | ||||||
|  |             "mov %cr4, %eax\n" | ||||||
|  |             "orl $0x4, %eax\n" | ||||||
|  |             "mov %eax, %cr4\n"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | String Processor::features_string() const | ||||||
|  | { | ||||||
|  |     StringBuilder builder; | ||||||
|  |     auto feature_to_str = | ||||||
|  |         [](CPUFeature f) -> const char* | ||||||
|  |         { | ||||||
|  |             switch (f) { | ||||||
|  |                 case CPUFeature::NX: | ||||||
|  |                     return "nx"; | ||||||
|  |                 case CPUFeature::PAE: | ||||||
|  |                     return "pae"; | ||||||
|  |                 case CPUFeature::PGE: | ||||||
|  |                     return "pge"; | ||||||
|  |                 case CPUFeature::RDRAND: | ||||||
|  |                     return "rdrand"; | ||||||
|  |                 case CPUFeature::RDSEED: | ||||||
|  |                     return "rdseed"; | ||||||
|  |                 case CPUFeature::SMAP: | ||||||
|  |                     return "smap"; | ||||||
|  |                 case CPUFeature::SMEP: | ||||||
|  |                     return "smep"; | ||||||
|  |                 case CPUFeature::SSE: | ||||||
|  |                     return "sse"; | ||||||
|  |                 case CPUFeature::TSC: | ||||||
|  |                     return "tsc"; | ||||||
|  |                 case CPUFeature::UMIP: | ||||||
|  |                     return "umip"; | ||||||
|  |                 // no default statement here intentionally so that we get
 | ||||||
|  |                 // a warning if a new feature is forgotten to be added here
 | ||||||
|  |             } | ||||||
|  |             // Shouldn't ever happen
 | ||||||
|  |             return "???"; | ||||||
|  |         }; | ||||||
|  |     bool first = true; | ||||||
|  |     for (u32 flag = 1; flag < sizeof(m_features) * 8; flag <<= 1) { | ||||||
|  |        if ((static_cast<u32>(m_features) & flag) != 0) { | ||||||
|  |            if (first) | ||||||
|  |                first = false; | ||||||
|  |            else | ||||||
|  |                builder.append(' '); | ||||||
|  |            auto str = feature_to_str(static_cast<CPUFeature>(flag)); | ||||||
|  |            builder.append(str, strlen(str)); | ||||||
|  |        } | ||||||
|  |     } | ||||||
|  |     return builder.build(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Processor::early_initialize(u32 cpu) | void Processor::early_initialize(u32 cpu) | ||||||
| { | { | ||||||
|     m_self = this; |     m_self = this; | ||||||
|  | @ -838,6 +873,8 @@ void Processor::early_initialize(u32 cpu) | ||||||
|     m_mm_data = nullptr; |     m_mm_data = nullptr; | ||||||
|     m_info = nullptr; |     m_info = nullptr; | ||||||
| 
 | 
 | ||||||
|  |     cpu_setup(); | ||||||
|  | 
 | ||||||
|     gdt_init(); |     gdt_init(); | ||||||
|     ASSERT(¤t() == this); // sanity check
 |     ASSERT(¤t() == this); // sanity check
 | ||||||
| } | } | ||||||
|  | @ -847,12 +884,9 @@ void Processor::initialize(u32 cpu) | ||||||
|     ASSERT(m_self == this); |     ASSERT(m_self == this); | ||||||
|     ASSERT(¤t() == this); // sanity check
 |     ASSERT(¤t() == this); // sanity check
 | ||||||
| 
 | 
 | ||||||
|     m_cpu = cpu; |     klog() << "CPU[" << id() << "]: Supported features: " << features_string(); | ||||||
|     m_in_irq = 0; |     if (!has_feature(CPUFeature::RDRAND)) | ||||||
| 
 |         klog() << "CPU[" << id() << "]: No RDRAND support detected, randomness will be poor"; | ||||||
|     m_idle_thread = nullptr; |  | ||||||
|     m_current_thread = nullptr; |  | ||||||
|     m_mm_data = nullptr; |  | ||||||
| 
 | 
 | ||||||
|     if (cpu == 0) |     if (cpu == 0) | ||||||
|         idt_init(); |         idt_init(); | ||||||
|  |  | ||||||
|  | @ -265,7 +265,6 @@ struct RegisterState; | ||||||
| 
 | 
 | ||||||
| const DescriptorTablePointer& get_gdtr(); | const DescriptorTablePointer& get_gdtr(); | ||||||
| const DescriptorTablePointer& get_idtr(); | const DescriptorTablePointer& get_idtr(); | ||||||
| void sse_init(); |  | ||||||
| void register_interrupt_handler(u8 number, void (*f)()); | void register_interrupt_handler(u8 number, void (*f)()); | ||||||
| void register_user_callable_interrupt_handler(u8 number, void (*f)()); | void register_user_callable_interrupt_handler(u8 number, void (*f)()); | ||||||
| GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number); | GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number); | ||||||
|  | @ -599,6 +598,19 @@ private: | ||||||
|     SplitQword m_start; |     SplitQword m_start; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | enum class CPUFeature : u32 { | ||||||
|  |     NX = (1 << 0), | ||||||
|  |     PAE = (1 << 1), | ||||||
|  |     PGE = (1 << 2), | ||||||
|  |     RDRAND = (1 << 3), | ||||||
|  |     RDSEED = (1 << 4), | ||||||
|  |     SMAP = (1 << 5), | ||||||
|  |     SMEP = (1 << 6), | ||||||
|  |     SSE = (1 << 7), | ||||||
|  |     TSC = (1 << 8), | ||||||
|  |     UMIP = (1 << 9) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class Thread; | class Thread; | ||||||
| struct TrapFrame; | struct TrapFrame; | ||||||
| 
 | 
 | ||||||
|  | @ -614,6 +626,8 @@ class ProcessorInfo; | ||||||
| struct MemoryManagerData; | struct MemoryManagerData; | ||||||
| 
 | 
 | ||||||
| class Processor { | class Processor { | ||||||
|  |     friend class ProcessorInfo; | ||||||
|  | 
 | ||||||
|     Processor* m_self; // must be first field (%fs offset 0x0)
 |     Processor* m_self; // must be first field (%fs offset 0x0)
 | ||||||
| 
 | 
 | ||||||
|     DescriptorTablePointer m_gdtr; |     DescriptorTablePointer m_gdtr; | ||||||
|  | @ -626,6 +640,7 @@ class Processor { | ||||||
| 
 | 
 | ||||||
|     TSS32 m_tss; |     TSS32 m_tss; | ||||||
|     static FPUState s_clean_fpu_state; |     static FPUState s_clean_fpu_state; | ||||||
|  |     CPUFeature m_features; | ||||||
| 
 | 
 | ||||||
|     ProcessorInfo* m_info; |     ProcessorInfo* m_info; | ||||||
|     MemoryManagerData* m_mm_data; |     MemoryManagerData* m_mm_data; | ||||||
|  | @ -640,6 +655,11 @@ class Processor { | ||||||
|     void write_gdt_entry(u16 selector, Descriptor& descriptor); |     void write_gdt_entry(u16 selector, Descriptor& descriptor); | ||||||
|     static Vector<Processor*>& processors(); |     static Vector<Processor*>& processors(); | ||||||
| 
 | 
 | ||||||
|  |     void cpu_detect(); | ||||||
|  |     void cpu_setup(); | ||||||
|  | 
 | ||||||
|  |     String features_string() const; | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
|     void early_initialize(u32 cpu); |     void early_initialize(u32 cpu); | ||||||
|     void initialize(u32 cpu); |     void initialize(u32 cpu); | ||||||
|  | @ -740,6 +760,11 @@ public: | ||||||
|         return s_clean_fpu_state; |         return s_clean_fpu_state; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     ALWAYS_INLINE bool has_feature(CPUFeature f) const | ||||||
|  |     { | ||||||
|  |         return (static_cast<u32>(m_features) & static_cast<u32>(f)) != 0; | ||||||
|  |     } | ||||||
|  |      | ||||||
|     void check_invoke_scheduler(); |     void check_invoke_scheduler(); | ||||||
|     void invoke_scheduler_async() { m_invoke_scheduler_async = true; } |     void invoke_scheduler_async() { m_invoke_scheduler_async = true; } | ||||||
|      |      | ||||||
|  | @ -846,22 +871,9 @@ public: | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void cpu_setup(u32 cpu); |  | ||||||
| 
 |  | ||||||
| extern bool g_cpu_supports_nx; |  | ||||||
| extern bool g_cpu_supports_pae; |  | ||||||
| extern bool g_cpu_supports_pge; |  | ||||||
| extern bool g_cpu_supports_rdrand; |  | ||||||
| extern bool g_cpu_supports_rdseed; |  | ||||||
| extern bool g_cpu_supports_smap; |  | ||||||
| extern bool g_cpu_supports_smep; |  | ||||||
| extern bool g_cpu_supports_sse; |  | ||||||
| extern bool g_cpu_supports_tsc; |  | ||||||
| extern bool g_cpu_supports_umip; |  | ||||||
| 
 |  | ||||||
| ALWAYS_INLINE void stac() | ALWAYS_INLINE void stac() | ||||||
| { | { | ||||||
|     if (!g_cpu_supports_smap) |     if (!Processor::current().has_feature(CPUFeature::SMAP)) | ||||||
|         return; |         return; | ||||||
|     asm volatile("stac" :: |     asm volatile("stac" :: | ||||||
|                      : "cc"); |                      : "cc"); | ||||||
|  | @ -869,7 +881,7 @@ ALWAYS_INLINE void stac() | ||||||
| 
 | 
 | ||||||
| ALWAYS_INLINE void clac() | ALWAYS_INLINE void clac() | ||||||
| { | { | ||||||
|     if (!g_cpu_supports_smap) |     if (!Processor::current().has_feature(CPUFeature::SMAP)) | ||||||
|         return; |         return; | ||||||
|     asm volatile("clac" :: |     asm volatile("clac" :: | ||||||
|                      : "cc"); |                      : "cc"); | ||||||
|  |  | ||||||
|  | @ -88,6 +88,9 @@ ProcessorInfo::ProcessorInfo(Processor& processor): | ||||||
|         copy_brand_string_part_to_buffer(2); |         copy_brand_string_part_to_buffer(2); | ||||||
|         m_brandstr = buffer; |         m_brandstr = buffer; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // Cache the CPU feature string
 | ||||||
|  |     m_features = m_processor.features_string(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ class ProcessorInfo | ||||||
|     Processor& m_processor; |     Processor& m_processor; | ||||||
|     String m_cpuid; |     String m_cpuid; | ||||||
|     String m_brandstr; |     String m_brandstr; | ||||||
|  |     String m_features; | ||||||
|     u32 m_display_model; |     u32 m_display_model; | ||||||
|     u32 m_display_family; |     u32 m_display_family; | ||||||
|     u32 m_stepping; |     u32 m_stepping; | ||||||
|  | @ -47,6 +48,7 @@ public: | ||||||
|      |      | ||||||
|     const String& cpuid() const { return m_cpuid; } |     const String& cpuid() const { return m_cpuid; } | ||||||
|     const String& brandstr() const { return m_brandstr; } |     const String& brandstr() const { return m_brandstr; } | ||||||
|  |     const String& features() const { return m_features; } | ||||||
|     u32 display_model() const { return m_display_model; } |     u32 display_model() const { return m_display_model; } | ||||||
|     u32 display_family() const { return m_display_family; } |     u32 display_family() const { return m_display_family; } | ||||||
|     u32 stepping() const { return m_stepping; } |     u32 stepping() const { return m_stepping; } | ||||||
|  |  | ||||||
|  | @ -773,6 +773,7 @@ Optional<KBuffer> procfs$cpuinfo(InodeIdentifier) | ||||||
|             builder.appendf("processor: %u\n", proc.id()); |             builder.appendf("processor: %u\n", proc.id()); | ||||||
|             builder.appendf("cpuid:     %s\n", info.cpuid().characters()); |             builder.appendf("cpuid:     %s\n", info.cpuid().characters()); | ||||||
|             builder.appendf("family:    %u\n", info.display_family()); |             builder.appendf("family:    %u\n", info.display_family()); | ||||||
|  |             builder.appendf("features:  %s\n", info.features().characters()); | ||||||
|             builder.appendf("model:     %u\n", info.display_model()); |             builder.appendf("model:     %u\n", info.display_model()); | ||||||
|             builder.appendf("stepping:  %u\n", info.stepping()); |             builder.appendf("stepping:  %u\n", info.stepping()); | ||||||
|             builder.appendf("type:      %u\n", info.type()); |             builder.appendf("type:      %u\n", info.type()); | ||||||
|  |  | ||||||
|  | @ -44,10 +44,12 @@ KernelRng& KernelRng::the() | ||||||
| 
 | 
 | ||||||
| KernelRng::KernelRng() | KernelRng::KernelRng() | ||||||
| { | { | ||||||
|     if (g_cpu_supports_rdseed || g_cpu_supports_rdrand) { |     bool supports_rdseed = Processor::current().has_feature(CPUFeature::RDSEED); | ||||||
|  |     bool supports_rdrand = Processor::current().has_feature(CPUFeature::RDRAND); | ||||||
|  |     if (supports_rdseed || supports_rdrand) { | ||||||
|         for (size_t i = 0; i < resource().pool_count * resource().reseed_threshold; ++i) { |         for (size_t i = 0; i < resource().pool_count * resource().reseed_threshold; ++i) { | ||||||
|             u32 value = 0; |             u32 value = 0; | ||||||
|             if (g_cpu_supports_rdseed) { |             if (supports_rdseed) { | ||||||
|                 asm volatile( |                 asm volatile( | ||||||
|                     "1:\n" |                     "1:\n" | ||||||
|                     "rdseed %0\n" |                     "rdseed %0\n" | ||||||
|  |  | ||||||
|  | @ -80,7 +80,7 @@ void MemoryManager::protect_kernel_image() | ||||||
|         pte.set_writable(false); |         pte.set_writable(false); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (g_cpu_supports_nx) { |     if (Processor::current().has_feature(CPUFeature::NX)) { | ||||||
|         // Disable execution of the kernel data and bss segments.
 |         // Disable execution of the kernel data and bss segments.
 | ||||||
|         for (size_t i = (FlatPtr)&start_of_kernel_data; i < (FlatPtr)&end_of_kernel_bss; i += PAGE_SIZE) { |         for (size_t i = (FlatPtr)&start_of_kernel_data; i < (FlatPtr)&end_of_kernel_bss; i += PAGE_SIZE) { | ||||||
|             auto& pte = ensure_pte(kernel_page_directory(), VirtualAddress(i)); |             auto& pte = ensure_pte(kernel_page_directory(), VirtualAddress(i)); | ||||||
|  |  | ||||||
|  | @ -237,7 +237,7 @@ void Region::map_individual_page_impl(size_t page_index) | ||||||
|             pte.set_writable(false); |             pte.set_writable(false); | ||||||
|         else |         else | ||||||
|             pte.set_writable(is_writable()); |             pte.set_writable(is_writable()); | ||||||
|         if (g_cpu_supports_nx) |         if (Processor::current().has_feature(CPUFeature::NX)) | ||||||
|             pte.set_execute_disabled(!is_executable()); |             pte.set_execute_disabled(!is_executable()); | ||||||
|         pte.set_user_allowed(is_user_accessible()); |         pte.set_user_allowed(is_user_accessible()); | ||||||
| #ifdef MM_DEBUG | #ifdef MM_DEBUG | ||||||
|  |  | ||||||
|  | @ -106,7 +106,6 @@ extern "C" [[noreturn]] void init() | ||||||
|     setup_serial_debug(); |     setup_serial_debug(); | ||||||
| 
 | 
 | ||||||
|     s_bsp_processor.early_initialize(0); |     s_bsp_processor.early_initialize(0); | ||||||
|     cpu_setup(0); |  | ||||||
| 
 | 
 | ||||||
|     kmalloc_init(); |     kmalloc_init(); | ||||||
|     slab_alloc_init(); |     slab_alloc_init(); | ||||||
|  | @ -169,7 +168,6 @@ extern "C" [[noreturn]] void init_ap(u32 cpu, Processor* processor_info) | ||||||
| 
 | 
 | ||||||
|     klog() << "CPU #" << cpu << " processor_info at " << VirtualAddress(FlatPtr(processor_info)); |     klog() << "CPU #" << cpu << " processor_info at " << VirtualAddress(FlatPtr(processor_info)); | ||||||
| 
 | 
 | ||||||
|     cpu_setup(cpu); |  | ||||||
|     processor_info->initialize(cpu); |     processor_info->initialize(cpu); | ||||||
|     MemoryManager::initialize(cpu); |     MemoryManager::initialize(cpu); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Tom
						Tom