aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2021-03-17 15:20:53 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2021-03-17 15:20:53 +0200
commit67b5d6ea184c432b21b3f07649ec3ba150a1d350 (patch)
treee35257ab15d0c69e96671dd405a0db911d89c2e5
parentMostly fix scheduler throwing page faults (diff)
downloadkernel.cpp-67b5d6ea184c432b21b3f07649ec3ba150a1d350.tar.xz
cpuid: show manufacturer and model
-rw-r--r--libk/stdlib.h6
-rw-r--r--libk/string.h13
-rw-r--r--src/cpu/cpu.cc35
-rw-r--r--src/cpu/cpu.h101
-rw-r--r--src/kernel.cc6
-rw-r--r--src/makefile1
6 files changed, 158 insertions, 4 deletions
diff --git a/libk/stdlib.h b/libk/stdlib.h
index 843cc14..0fd1ad8 100644
--- a/libk/stdlib.h
+++ b/libk/stdlib.h
@@ -62,3 +62,9 @@ void printk(const T& a, const Args&... x) {
}
extern "C" __attribute__((__noreturn__)) void abort();
+
+#define runtime_assert(x, msg) \
+ if (!x) { \
+ printk(__FILE__, ':', __LINE__, ' ', msg); \
+ abort(); \
+ }
diff --git a/libk/string.h b/libk/string.h
index 30824b8..d0a0b32 100644
--- a/libk/string.h
+++ b/libk/string.h
@@ -1,14 +1,20 @@
#pragma once
#include <types.h>
+extern "C" {
+void* memcpy(void* dstptr, const void* srcptr, const size_t n);
+void* memset(void* bufptr, const int value, const size_t n);
+void* memmove(void* dstptr, const void* srcptr, const size_t n);
+int memcmp(const void* aptr, const void* bptr, const size_t n);
+}
+
/**
* Calculate the length of the string (in bytes) pointed to by str, excluding
* the terminating null character.
*/
constexpr size_t strlen(const char* str) {
size_t len = 0;
- while (str[len] != '\0')
- ++len;
+ while (str[len] != '\0') ++len;
return len;
}
@@ -32,8 +38,7 @@ public:
operator bool() const { return reverse ? (pos >= 0) : (pos < length); }
explicit ViewIterator(const char* b, size_t l, bool r = false) : buffer(b), length(l), reverse(r) {
- if (reverse)
- pos = length - 1;
+ if (reverse) pos = length - 1;
};
private:
diff --git a/src/cpu/cpu.cc b/src/cpu/cpu.cc
new file mode 100644
index 0000000..0c9403f
--- /dev/null
+++ b/src/cpu/cpu.cc
@@ -0,0 +1,35 @@
+#include "cpu.h"
+#include <stdlib.h>
+
+static_assert(sizeof(CPU::features_t) == 2 * sizeof(uint32_t));
+
+CPU::CPU() {
+ static_assert(sizeof(CPU::version_t) == sizeof(uint32_t));
+ struct {
+ uint32_t d;
+ uint32_t c;
+ uint32_t b;
+ uint32_t a;
+ } __attribute__((packed)) r;
+ size_t highest_param = 0;
+
+ for (int i = 0; i <= highest_param; ++i) {
+ asm volatile("cpuid" : "=a"(r.a), "=b"(r.b), "=c"(r.c), "=d"(r.d) : "a"(i));
+
+ switch (i) {
+ case 0:
+ highest_param = static_cast<size_t>(r.a);
+ memcpy(&m_manufacturer[0], &r.b, sizeof(r.b));
+ memcpy(&m_manufacturer[4], &r.d, sizeof(r.d));
+ memcpy(&m_manufacturer[8], &r.c, sizeof(r.c));
+ break;
+ case 1:
+ memcpy(&m_info, &r.a, sizeof(r.a));
+ memcpy(&m_features, &r.d, sizeof(CPU::features_t));
+ break;
+ default:
+ return;
+ }
+ }
+
+}
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
new file mode 100644
index 0000000..2dc9cbe
--- /dev/null
+++ b/src/cpu/cpu.h
@@ -0,0 +1,101 @@
+#pragma once
+
+#include <types.h>
+
+class CPU {
+public:
+ struct features_t {
+ bool fpu : 1 = false; // onboard x87 fpu
+ bool vme : 1 = false; // virtual 8086 mode
+ bool de : 1 = false; // debugging extensions
+ bool pse : 1 = false; // page size extension
+ bool tsc : 1 = false; // time stamp counter
+ bool msr : 1 = false; // model specific registers
+ bool pae : 1 = false; // physical address extension
+ bool mce : 1 = false; // machine check exception
+ bool cx8 : 1 = false; // compare and swap instruction
+ bool apic : 1 = false; // onboard apic
+ bool __r0 : 1 = false;
+ bool sep : 1 = false; // sysenter and sysexit
+ bool mtrr : 1 = false; // memory type range registers
+ bool pge : 1 = false; // page global enable bit
+ bool mca : 1 = false; // machine check architecture
+ bool cmov : 1 = false; // conditional move
+ bool pat : 1 = false; // page attribute table
+ bool pse36 : 1 = false; // 36-bit page size extension
+ bool psn : 1 = false; // processor serial number
+ bool clfsh : 1 = false; // clflish
+ bool __r1 : 1 = false;
+ bool ds : 1 = false; // debug store
+ bool acpi : 1 = false; // onboard thermal control for acpi
+ bool mmx : 1 = false; // mmx extension
+ bool fxsr : 1 = false; // fxsave, fxrestor
+ bool sse : 1 = false; // sse extension
+ bool sse2 : 1 = false; // sse2 extension
+ bool ss : 1 = false; // cpu cache implements self-snoop
+ bool htt : 1 = false; // hyper-threading
+ bool tm : 1 = false; // thermal monitor auto-limits temperature
+ bool ia64 : 1 = false; // ia64 processor emulating x86
+ bool pbe : 1 = false; // pending break enable
+
+ bool sse3 : 1 = false; // sse3 extension
+ bool pclmulqdq : 1 = false; // pclmulqdq
+ bool dtes64 : 1 = false; // 64-bit debug store
+ bool monitor : 1 = false; // monitor and mwait instructions (sse3)
+ bool ds_cpl : 1 = false; // CPL qualified debug store
+ bool vmx : 1 = false; // virtual machine extensions
+ bool smx : 1 = false; // safer mode extensions
+ bool est : 1 = false; // enahnced speedstep
+ bool tm2 : 1 = false; // thermal monitor 2
+ bool ssse3 : 1 = false; // supplemental sse3
+ bool cnxt_id : 1 = false; // L1 context ID
+ bool sdbg : 1 = false; // Silicon Debug interface
+ bool fma : 1 = false; // fused multiply-add
+ bool cx16 : 1 = false; // cmpxchg16b instruction
+ bool xtpr : 1 = false; // can disable sending task priority messages
+ bool pdcm : 1 = false; // perfom and debug capability
+ bool __r2 : 1 = false;
+ bool pcid : 1 = false; // process context identifiers
+ bool dca : 1 = false; // direct cache access for DMA writes
+ bool sse41 : 1 = false; // sse 4.1
+ bool sse42 : 1 = false; // sse 4.2
+ bool x2apic : 1 = false; // x2APIX
+ bool movbe : 1 = false; // movbe instruction
+ bool popcnt : 1 = false; // popcnt instruction
+ bool tsc_deadline : 1 = false; // apic implements one-shot operation using tsc deadline
+ bool aes : 1 = false; // aes instruction set
+ bool xsave : 1 = false; // xsave, xrestor, xsetbv, xgetbv
+ bool oxsave : 1 = false; // xsave enabled by OS
+ bool avx : 1 = false; // advanced vector extensions
+ bool f16c : 1 = false; // f16c fp feature
+ bool rdrnd : 1 = false; // rdrand
+ bool hypervisor : 1 = false; // hypervisor present
+ } __attribute__((packed));
+
+ CPU();
+ ~CPU() = default;
+
+ const char* manufacturer() const { return m_manufacturer; }
+ uint8_t family() const { return m_info.family == 15 ? m_info.family + m_info.family_ex : m_info.family; }
+ uint8_t model() const {
+ return (m_info.model == 6 || m_info.model == 15) ? (static_cast<uint8_t>(m_info.model_ex << 4) + m_info.model)
+ : m_info.model;
+ }
+ uint8_t stepping() const { return m_info.stepping; }
+ auto features() const { return m_features; }
+
+private:
+ char m_manufacturer[13] = {'\0'};
+ struct version_t {
+ uint8_t stepping : 4 = 0;
+ uint8_t model : 4 = 0;
+ uint8_t family : 4 = 0;
+ uint8_t type : 2 = 0;
+ uint8_t reserved_1 : 2 = 0;
+ uint8_t model_ex : 4 = 0;
+ uint8_t family_ex : 8 = 0;
+ uint8_t reserved_2 : 4 = 0;
+ } __attribute__((packed)) m_info;
+
+ features_t m_features;
+};
diff --git a/src/kernel.cc b/src/kernel.cc
index 0d8874c..3110419 100644
--- a/src/kernel.cc
+++ b/src/kernel.cc
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <types.h>
#include "cga.h"
+#include "cpu/cpu.h"
#include "gdt.h"
#include "idt.h"
#include "keyboard.h"
@@ -41,6 +42,11 @@ void kernel_main([[maybe_unused]] uint32_t mb_magic, [[maybe_unused]] uint32_t m
#endif
printk("Hello, kernel World!\n");
+ CPU core0;
+ printk("cpuid: ", core0.manufacturer(), " family ", core0.family(), " model ", core0.model(), " stepping ",
+ core0.stepping(), '\n');
+ runtime_assert(core0.features().fpu, "CPU lacks fpu");
+ runtime_assert(core0.features().cx8, "CPU lacks cx8");
dump_address();
// dump_gdt();
diff --git a/src/makefile b/src/makefile
index d3b3c47..68ec6d6 100644
--- a/src/makefile
+++ b/src/makefile
@@ -3,6 +3,7 @@ AS_OBJ += src/boot.o \
CXX_OBJ += src/kernel.o \
src/kernel/dump_gdt.o src/kernel/dump_multiboot.o \
+ src/cpu/cpu.o \
src/gdt.o \
src/gdt/segmentdescriptor.o \
src/idt.o \