summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2013-07-05 00:22:10 +0200
committerRichard Braun <rbraun@sceen.net>2013-07-05 00:22:10 +0200
commit74ed00bc034acf5e479865b00885be184a67b0a6 (patch)
tree18dc119a1722b1a6e918fdfad3881cb308dcae00
parent9ec78141b572c7db135a28358c06cf22ad6feba4 (diff)
x86/cpu: obtain physical/virtual address widths
-rw-r--r--arch/x86/machine/cpu.c15
-rw-r--r--arch/x86/machine/cpu.h2
2 files changed, 16 insertions, 1 deletions
diff --git a/arch/x86/machine/cpu.c b/arch/x86/machine/cpu.c
index f07e6d1a..4767789a 100644
--- a/arch/x86/machine/cpu.c
+++ b/arch/x86/machine/cpu.c
@@ -327,8 +327,10 @@ cpu_init(struct cpu *cpu)
memcpy(cpu->vendor_id + 8, &ecx, sizeof(ecx));
cpu->vendor_id[sizeof(cpu->vendor_id) - 1] = '\0';
- /* Initialized if the processor supports brand strings */
+ /* Some fields are only initialized if supported by the processor */
cpu->model_name[0] = '\0';
+ cpu->phys_addr_width = 0;
+ cpu->virt_addr_width = 0;
assert(max_basic >= 1);
@@ -394,6 +396,13 @@ cpu_init(struct cpu *cpu)
cpu->model_name[sizeof(cpu->model_name) - 1] = '\0';
}
+ if (max_extended >= 0x80000008) {
+ eax = 0x80000008;
+ cpu_cpuid(&eax, &ebx, &ecx, &edx);
+ cpu->phys_addr_width = (unsigned short)eax & 0xff;
+ cpu->virt_addr_width = ((unsigned short)eax >> 8) & 0xff;
+ }
+
cpu->state = CPU_STATE_ON;
}
@@ -441,6 +450,10 @@ cpu_info(const struct cpu *cpu)
if (strlen(cpu->model_name) > 0)
printk("cpu%u: %s\n", cpu->id, cpu->model_name);
+
+ if ((cpu->phys_addr_width != 0) && (cpu->virt_addr_width != 0))
+ printk("cpu%u: address widths: physical: %hu, virtual: %hu\n",
+ cpu->id, cpu->phys_addr_width, cpu->virt_addr_width);
}
void __init
diff --git a/arch/x86/machine/cpu.h b/arch/x86/machine/cpu.h
index d655496e..3c13911b 100644
--- a/arch/x86/machine/cpu.h
+++ b/arch/x86/machine/cpu.h
@@ -245,6 +245,8 @@ struct cpu {
unsigned int features2;
unsigned int features3;
unsigned int features4;
+ unsigned short phys_addr_width;
+ unsigned short virt_addr_width;
char gdt[CPU_GDT_SIZE] __aligned(8);
struct cpu_tss tss;
#ifndef __LP64__