ChangeSet 1.1564, 2005/05/26 16:35:14+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx
Port CPU setup code from Linux 2.6.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
arch/x86/Makefile | 9
arch/x86/cpu/amd.c | 254 +++++++++++++++++
arch/x86/cpu/centaur.c | 477 +++++++++++++++++++++++++++++++++
arch/x86/cpu/common.c | 579 +++++++++++++++++++++++++++++++++++++++++
arch/x86/cpu/cpu.h | 31 ++
arch/x86/cpu/cyrix.c | 400 ++++++++++++++++++++++++++++
arch/x86/cpu/intel.c | 244 +++++++++++++++++
arch/x86/cpu/intel_cacheinfo.c | 142 ++++++++++
arch/x86/cpu/rise.c | 54 +++
arch/x86/cpu/transmeta.c | 108 +++++++
arch/x86/setup.c | 254 -----------------
include/asm-x86/config.h | 5
include/asm-x86/cpufeature.h | 42 ++
include/asm-x86/msr.h | 26 -
include/asm-x86/processor.h | 75 +++--
15 files changed, 2398 insertions(+), 302 deletions(-)
diff -Nru a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile 2005-05-26 12:01:55 -04:00
+++ b/xen/arch/x86/Makefile 2005-05-26 12:01:55 -04:00
@@ -6,6 +6,14 @@
OBJS += $(patsubst %.c,%.o,$(wildcard acpi/*.c))
OBJS += $(patsubst %.c,%.o,$(wildcard mtrr/*.c))
OBJS += $(patsubst %.c,%.o,$(wildcard genapic/*.c))
+OBJS += $(patsubst %.c,%.o,$(wildcard cpu/*.c))
+
+ifeq ($(TARGET_SUBARCH),x86_64)
+OBJS := $(subst cpu/centaur.o,,$(OBJS))
+OBJS := $(subst cpu/cyrix.o,,$(OBJS))
+OBJS := $(subst cpu/rise.o,,$(OBJS))
+OBJS := $(subst cpu/transmeta.o,,$(OBJS))
+endif
OBJS := $(subst $(TARGET_SUBARCH)/asm-offsets.o,,$(OBJS))
@@ -38,6 +46,7 @@
rm -f mtrr/*.o mtrr/*~ mtrr/core
rm -f acpi/*.o acpi/*~ acpi/core
rm -f genapic/*.o genapic/*~ genapic/core
+ rm -f cpu/*.o cpu/*~ cpu/core
delete-unfresh-files:
# nothing
diff -Nru a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/xen/arch/x86/cpu/amd.c 2005-05-26 12:01:55 -04:00
@@ -0,0 +1,254 @@
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/bitops.h>
+#include <xen/mm.h>
+#include <xen/smp.h>
+#include <asm/io.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+
+#include "cpu.h"
+
+#define num_physpages 0
+
+/*
+ * B step AMD K6 before B 9730xxxx have hardware bugs that can cause
+ * misexecution of code under Linux. Owners of such processors should
+ * contact AMD for precise details and a CPU swap.
+ *
+ * See http://www.multimania.com/poulot/k6bug.html
+ * http://www.amd.com/K6/k6docs/revgd.html
+ *
+ * The following test is erm.. interesting. AMD neglected to up
+ * the chip setting when fixing the bug but they also tweaked some
+ * performance at the same time..
+ */
+
+extern void vide(void);
+__asm__(".align 4\nvide: ret");
+
+static void __init init_amd(struct cpuinfo_x86 *c)
+{
+ u32 l, h;
+ int mbytes = num_physpages >> (20-PAGE_SHIFT);
+ int r;
+
+ /*
+ * FIXME: We should handle the K5 here. Set up the write
+ * range and also turn on MSR 83 bits 4 and 31 (write alloc,
+ * no bus pipeline)
+ */
+
+ /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
+ 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
+ clear_bit(0*32+31, c->x86_capability);
+
+ r = get_model_name(c);
+
+ switch(c->x86)
+ {
+ case 4:
+ /*
+ * General Systems BIOSen alias the cpu frequency registers
+ * of the Elan at 0x000df000. Unfortuantly, one of the Linux
+ * drivers subsequently pokes it, and changes the CPU speed.
+ * Workaround : Remove the unneeded alias.
+ */
+#define CBAR (0xfffc) /* Configuration Base Address (32-bit) */
+#define CBAR_ENB (0x80000000)
+#define CBAR_KEY (0X000000CB)
+ if (c->x86_model==9 || c->x86_model == 10) {
+ if (inl (CBAR) & CBAR_ENB)
+ outl (0 | CBAR_KEY, CBAR);
+ }
+ break;
+ case 5:
+ if( c->x86_model < 6 )
+ {
+ /* Based on AMD doc 20734R - June 2000 */
+ if ( c->x86_model == 0 ) {
+ clear_bit(X86_FEATURE_APIC,
c->x86_capability);
+ set_bit(X86_FEATURE_PGE,
c->x86_capability);
+ }
+ break;
+ }
+
+ if ( c->x86_model == 6 && c->x86_mask == 1 ) {
+ const int K6_BUG_LOOP = 1000000;
+ int n;
+ void (*f_vide)(void);
+ unsigned long d, d2;
+
+ printk(KERN_INFO "AMD K6 stepping B detected -
");
+
+ /*
+ * It looks like AMD fixed the 2.6.2 bug and
improved indirect
+ * calls at the same time.
+ */
+
+ n = K6_BUG_LOOP;
+ f_vide = vide;
+ rdtscl(d);
+ while (n--)
+ f_vide();
+ rdtscl(d2);
+ d = d2-d;
+
+ /* Knock these two lines out if it debugs out
ok */
+ printk(KERN_INFO "AMD K6 stepping B detected -
");
+ /* -- cut here -- */
+ if (d > 20*K6_BUG_LOOP)
+ printk("system stability may be
impaired when more than 32 MB are used.\n");
+ else
+ printk("probably OK (after
B9730xxxx).\n");
+ printk(KERN_INFO "Please see
http://membres.lycos.fr/poulot/k6bug.html\n");
+ }
+
+ /* K6 with old style WHCR */
+ if (c->x86_model < 8 ||
+ (c->x86_model== 8 && c->x86_mask < 8)) {
+ /* We can only write allocate on the low 508Mb
*/
+ if(mbytes>508)
+ mbytes=508;
+
+ rdmsr(MSR_K6_WHCR, l, h);
+ if ((l&0x0000FFFF)==0) {
+ unsigned long flags;
+ l=(1<<0)|((mbytes/4)<<1);
+ local_irq_save(flags);
+ wbinvd();
+ wrmsr(MSR_K6_WHCR, l, h);
+ local_irq_restore(flags);
+ printk(KERN_INFO "Enabling old style K6
write allocation for %d Mb\n",
+ mbytes);
+ }
+ break;
+ }
+
+ if ((c->x86_model == 8 && c->x86_mask >7) ||
+ c->x86_model == 9 || c->x86_model == 13) {
+ /* The more serious chips .. */
+
+ if(mbytes>4092)
+ mbytes=4092;
+
+ rdmsr(MSR_K6_WHCR, l, h);
+ if ((l&0xFFFF0000)==0) {
+ unsigned long flags;
+ l=((mbytes>>2)<<22)|(1<<16);
+ local_irq_save(flags);
+ wbinvd();
+ wrmsr(MSR_K6_WHCR, l, h);
+ local_irq_restore(flags);
+ printk(KERN_INFO "Enabling new style K6
write allocation for %d Mb\n",
+ mbytes);
+ }
+
+ /* Set MTRR capability flag if appropriate */
+ if (c->x86_model == 13 || c->x86_model == 9 ||
+ (c->x86_model == 8 && c->x86_mask >= 8))
+ set_bit(X86_FEATURE_K6_MTRR,
c->x86_capability);
+ break;
+ }
+ break;
+
+ case 6: /* An Athlon/Duron */
+
+ /* Bit 15 of Athlon specific MSR 15, needs to be 0
+ * to enable SSE on Palomino/Morgan/Barton CPU's.
+ * If the BIOS didn't enable it already, enable it here.
+ */
+ if (c->x86_model >= 6 && c->x86_model <= 10) {
+ if (!cpu_has(c, X86_FEATURE_XMM)) {
+ printk(KERN_INFO "Enabling disabled
K7/SSE Support.\n");
+ rdmsr(MSR_K7_HWCR, l, h);
+ l &= ~0x00008000;
+ wrmsr(MSR_K7_HWCR, l, h);
+ set_bit(X86_FEATURE_XMM,
c->x86_capability);
+ }
+ }
+
+ /* It's been determined by AMD that Athlons since model
8 stepping 1
+ * are more robust with CLK_CTL set to 200xxxxx instead
of 600xxxxx
+ * As per AMD technical note 27212 0.2
+ */
+ if ((c->x86_model == 8 && c->x86_mask>=1) ||
(c->x86_model > 8)) {
+ rdmsr(MSR_K7_CLK_CTL, l, h);
+ if ((l & 0xfff00000) != 0x20000000) {
+ printk ("CPU: CLK_CTL MSR was %x.
Reprogramming to %x\n", l,
+ ((l & 0x000fffff)|0x20000000));
+ wrmsr(MSR_K7_CLK_CTL, (l &
0x000fffff)|0x20000000, h);
+ }
+ }
+ break;
+ }
+
+ switch (c->x86) {
+ case 15:
+ set_bit(X86_FEATURE_K8, c->x86_capability);
+ break;
+ case 6:
+ set_bit(X86_FEATURE_K7, c->x86_capability);
+ break;
+ }
+
+ display_cacheinfo(c);
+ detect_ht(c);
+
+#ifdef CONFIG_X86_HT
+ /* AMD dual core looks like HT but isn't really. Hide it from the
+ scheduler. This works around problems with the domain scheduler.
+ Also probably gives slightly better scheduling and disables
+ SMT nice which is harmful on dual core.
+ TBD tune the domain scheduler for dual core. */
+ if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
+ smp_num_siblings = 1;
+#endif
+
+ if (cpuid_eax(0x80000000) >= 0x80000008) {
+ c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
+ if (c->x86_num_cores & (c->x86_num_cores - 1))
+ c->x86_num_cores = 1;
+ }
+}
+
+static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
+{
+ /* AMD errata T13 (order #21922) */
+ if ((c->x86 == 6)) {
+ if (c->x86_model == 3 && c->x86_mask == 0) /* Duron Rev A0
*/
+ size = 64;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|