Check CPUID info, switch cpu flag to Broadwell

This commit is contained in:
Justin C. Miller
2018-04-29 23:50:56 -07:00
parent 99222d8ab9
commit 2d4e7cfdee
4 changed files with 117 additions and 0 deletions

View File

@@ -116,6 +116,7 @@ QEMUOPTS += -drive file=$(BUILD_D)/fs.img,format=raw
QEMUOPTS += -smp $(CPUS) -m 512
QEMUOPTS += -d mmu,guest_errors,int -D popcorn.log
QEMUOPTS += -no-reboot
QEMUOPTS += -cpu Broadwell
QEMUOPTS += $(QEMUEXTRA)

63
src/kernel/cpu.cpp Normal file
View File

@@ -0,0 +1,63 @@
#include <stdint.h>
#include "kutil/memory.h"
#include "cpu.h"
#include "log.h"
inline static void
__cpuid(
uint32_t leaf,
uint32_t subleaf,
uint32_t *eax,
uint32_t *ebx = nullptr,
uint32_t *ecx = nullptr,
uint32_t *edx = nullptr)
{
uint32_t a, b, c, d;
__asm__ __volatile__ ( "cpuid"
: "=a"(a), "=b"(b), "=c"(c), "=d"(d)
: "a"(leaf), "c"(subleaf)
);
if (eax) *eax = a;
if (ebx) *ebx = b;
if (ecx) *ecx = c;
if (edx) *edx = d;
}
cpu_id::cpu_id()
{
__cpuid(0, 0,
&m_high_leaf,
reinterpret_cast<uint32_t *>(&m_vendor_id[0]),
reinterpret_cast<uint32_t *>(&m_vendor_id[8]),
reinterpret_cast<uint32_t *>(&m_vendor_id[4]));
uint32_t eax = 0;
__cpuid(0, 1, &eax);
m_stepping = eax & 0xf;
m_model = (eax >> 4) & 0xf;
m_family = (eax >> 8) & 0xf;
m_cpu_type = (eax >> 12) & 0x3;
uint32_t ext_model = (eax >> 16) & 0xf;
uint32_t ext_family = (eax >> 20) & 0xff;
if (m_family == 0x6 || m_family == 0xf)
m_model = (ext_model << 4) + m_model;
if (m_family == 0xf)
m_family += ext_family;
}
cpu_id::regs
cpu_id::get(uint32_t leaf, uint32_t sub) const
{
if (leaf > m_high_leaf) return {};
regs ret;
__cpuid(leaf, sub, &ret.eax, &ret.ebx, &ret.ecx, &ret.edx);
return ret;
}

40
src/kernel/cpu.h Normal file
View File

@@ -0,0 +1,40 @@
#pragma once
class cpu_id
{
public:
struct regs {
uint32_t eax, ebx, ecx, edx;
regs() : eax(0), ebx(0), ecx(0), edx(0) {}
regs(uint32_t a, uint32_t b, uint32_t c, uint32_t d) : eax(a), ebx(b), ecx(c), edx(d) {}
regs(const regs &r) : eax(r.eax), ebx(r.ebx), ecx(r.ecx), edx(r.edx) {}
bool eax_bit(unsigned bit) { return (eax >> bit) & 0x1; }
bool ebx_bit(unsigned bit) { return (ebx >> bit) & 0x1; }
bool ecx_bit(unsigned bit) { return (ecx >> bit) & 0x1; }
bool edx_bit(unsigned bit) { return (edx >> bit) & 0x1; }
};
cpu_id();
regs get(uint32_t leaf, uint32_t sub = 0) const;
inline const char * vendor_id() const { return m_vendor_id; }
inline uint8_t cpu_type() const { return m_cpu_type; }
inline uint8_t stepping() const { return m_stepping; }
inline uint16_t family() const { return m_family; }
inline uint16_t model() const { return m_model; }
private:
void read();
uint32_t m_high_leaf;
char m_vendor_id[13];
uint8_t m_cpu_type;
uint8_t m_stepping;
uint16_t m_family;
uint16_t m_model;
};

View File

@@ -3,6 +3,7 @@
#include "kutil/memory.h"
#include "console.h"
#include "cpu.h"
#include "device_manager.h"
#include "font.h"
#include "interrupts.h"
@@ -48,6 +49,18 @@ kernel_main(popcorn_data *header)
log::init(cons);
cpu_id cpu;
log::info(logs::boot, "CPU Vendor: %s", cpu.vendor_id());
log::info(logs::boot, "CPU Family %x Model %x Stepping %x",
cpu.family(), cpu.model(), cpu.stepping());
cpu_id::regs cpu_info = cpu.get(1);
log::info(logs::boot, "LAPIC Supported: %s",
cpu_info.edx_bit(9) ? "yes" : "no");
log::info(logs::boot, "x2APIC Supported: %s",
cpu_info.ecx_bit(21) ? "yes" : "no");
page_manager *pager = new (&g_page_manager) page_manager;
pager->mark_offset_pointer(&header->frame_buffer, header->frame_buffer_length);