summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/amd64/machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64/amd64/machdep.c')
-rw-r--r--sys/arch/amd64/amd64/machdep.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 9b65d6e..40950f9 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -44,6 +44,8 @@
#include <machine/intr.h>
#include <machine/cdefs.h>
#include <machine/isa/i8042var.h>
+#include <dev/cons/cons.h>
+#include <string.h>
#define pr_trace(fmt, ...) kprintf("cpu: " fmt, ##__VA_ARGS__)
#define pr_error(...) pr_trace(__VA_ARGS__)
@@ -185,9 +187,10 @@ enable_simd(void)
}
static void
-cpu_check_feat(struct cpu_info *ci)
+cpu_get_info(struct cpu_info *ci)
{
- uint32_t unused, ebx;
+ uint32_t eax, ebx, unused;
+ uint8_t ext_model, ext_family;
/* Extended features */
CPUID(0x07, unused, ebx, unused, unused);
@@ -195,6 +198,33 @@ cpu_check_feat(struct cpu_info *ci)
ci->feat |= CPU_FEAT_SMEP;
if (ISSET(ebx, BIT(20)))
ci->feat |= CPU_FEAT_SMAP;
+
+ /*
+ * Processor info and feature bits
+ */
+ CPUID(0x01, eax, unused, unused, unused);
+ ci->model = (eax >> 4) & 0xF;
+ ci->family = (eax >> 8) & 0xF;
+
+ /*
+ * If the family ID is 15 then the actual family
+ * ID is the sum of the extended family and the
+ * family ID fields.
+ */
+ if (ci->family == 0xF) {
+ ext_family = (eax >> 20) & 0xFF;
+ ci->family += ext_family;
+ }
+
+ /*
+ * If the family has the value of either 6 or 15,
+ * then the extended model number would be used.
+ * Slap them together if this is the case.
+ */
+ if (ci->family == 6 || ci->family == 15) {
+ ext_model = (eax >> 16) & 0xF;
+ ci->model |= (ext_model << 4);
+ }
}
void
@@ -224,6 +254,7 @@ md_backtrace(void)
uintptr_t rip;
off_t off;
const char *name;
+ char line[256];
__ASMV("mov %%rbp, %0" : "=r" (rbp) :: "memory");
while (1) {
@@ -236,7 +267,8 @@ md_backtrace(void)
if (name == NULL)
name = "???";
- kprintf(OMIT_TIMESTAMP "%p @ <%s+0x%x>\n", rip, name, off);
+ snprintf(line, sizeof(line), "%p @ <%s+0x%x>\n", rip, name, off);
+ cons_putstr(&g_root_scr, line, strlen(line));
}
}
@@ -294,6 +326,10 @@ this_cpu(void)
{
struct cpu_info *ci;
+ if (rdmsr(IA32_GS_BASE) == 0) {
+ return NULL;
+ }
+
/*
* This might look crazy but we are just leveraging the "m"
* constraint to add the offset of the self field within
@@ -375,7 +411,7 @@ cpu_startup(struct cpu_info *ci)
init_tss(ci);
try_mitigate_spectre();
- cpu_check_feat(ci);
+ cpu_get_info(ci);
cpu_enable_smep();
enable_simd();