blob: a6761f202a840c872ff665b64925af9c9ce46944 [file] [log] [blame]
Martin Roth9df9e9392016-01-12 15:55:28 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Lee Leahy2da95242015-06-12 17:30:33 -070014#include <console/console.h>
15#include <cpu/cpu.h>
16#include <arch/io.h>
17#include <string.h>
18#include <cpu/x86/mtrr.h>
19#include <cpu/x86/msr.h>
20#include <cpu/x86/lapic.h>
21#include <arch/cpu.h>
22#include <device/path.h>
23#include <device/device.h>
24#include <smp/spinlock.h>
25
Stefan Reinauer96938852015-06-18 01:23:48 -070026#ifndef __x86_64__
Lee Leahy2da95242015-06-12 17:30:33 -070027/* Standard macro to see if a specific flag is changeable */
28static inline int flag_is_changeable_p(uint32_t flag)
29{
30 uint32_t f1, f2;
31
32 asm(
33 "pushfl\n\t"
34 "pushfl\n\t"
35 "popl %0\n\t"
36 "movl %0,%1\n\t"
37 "xorl %2,%0\n\t"
38 "pushl %0\n\t"
39 "popfl\n\t"
40 "pushfl\n\t"
41 "popl %0\n\t"
42 "popfl\n\t"
43 : "=&r" (f1), "=&r" (f2)
44 : "ir" (flag));
45 return ((f1^f2) & flag) != 0;
46}
47
48/* Probe for the CPUID instruction */
49int cpu_have_cpuid(void)
50{
51 return flag_is_changeable_p(X86_EFLAGS_ID);
52}
53
Stefan Reinauer96938852015-06-18 01:23:48 -070054#else
55
56int cpu_have_cpuid(void)
57{
58 return 1;
59}
60#endif
61
Lee Leahy2da95242015-06-12 17:30:33 -070062int cpu_cpuid_extended_level(void)
63{
64 return cpuid_eax(0x80000000);
65}
66
67int cpu_phys_address_size(void)
68{
69 if (!(cpu_have_cpuid()))
70 return 32;
71
72 if (cpu_cpuid_extended_level() >= 0x80000008)
73 return cpuid_eax(0x80000008) & 0xff;
74
75 if (cpuid_edx(1) & (CPUID_FEATURE_PAE | CPUID_FEATURE_PSE36))
76 return 36;
77 return 32;
78}