summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/p6/Config.lb7
-rw-r--r--src/cpu/p6/apic_timer.c26
-rw-r--r--src/cpu/p6/chip.h5
-rw-r--r--src/cpu/p6/cpufixup.c24
-rw-r--r--src/cpu/p6/disable_mmx_sse.inc27
-rw-r--r--src/cpu/p6/enable_mmx_sse.inc25
6 files changed, 113 insertions, 1 deletions
diff --git a/src/cpu/p6/Config.lb b/src/cpu/p6/Config.lb
index d4918f9147..8242a6e874 100644
--- a/src/cpu/p6/Config.lb
+++ b/src/cpu/p6/Config.lb
@@ -1,5 +1,10 @@
uses INTEL_PPRO_MTRR
+uses CPU_FIXUP
dir /cpu/p5
-object cpufixup.o
+config chip.h
+if CPU_FIXUP
+ object cpufixup.o
+ object apic_timer.o
+end
object mtrr.o
object pgtbl.o
diff --git a/src/cpu/p6/apic_timer.c b/src/cpu/p6/apic_timer.c
new file mode 100644
index 0000000000..fa7e9b905f
--- /dev/null
+++ b/src/cpu/p6/apic_timer.c
@@ -0,0 +1,26 @@
+#include <stdint.h>
+#include <delay.h>
+#include <cpu/p6/msr.h>
+#include <cpu/p6/apic.h>
+
+void init_timer(void)
+{
+ /* Set the apic timer to no interrupts and periodic mode */
+ apic_write(APIC_LVTT, (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0));
+ /* Set the divider to 1, no divider */
+ apic_write(APIC_TDCR, APIC_TDR_DIV_1);
+ /* Set the initial counter to 0xffffffff */
+ apic_write(APIC_TMICT, 0xffffffff);
+}
+
+void udelay(unsigned usecs)
+{
+ uint32_t start, value, ticks;
+ /* Calculate the number of ticks to run, our FSB runs a 200Mhz */
+ ticks = usecs * 200;
+ start = apic_read(APIC_TMCCT);
+ do {
+ value = apic_read(APIC_TMCCT);
+ } while((start - value) < ticks);
+
+}
diff --git a/src/cpu/p6/chip.h b/src/cpu/p6/chip.h
new file mode 100644
index 0000000000..bfcdf79ed7
--- /dev/null
+++ b/src/cpu/p6/chip.h
@@ -0,0 +1,5 @@
+extern struct chip_control cpu_p6_control;
+
+struct cpu_p6_config {
+ int nothing;
+};
diff --git a/src/cpu/p6/cpufixup.c b/src/cpu/p6/cpufixup.c
index e5cd3fc017..f611524fab 100644
--- a/src/cpu/p6/cpufixup.c
+++ b/src/cpu/p6/cpufixup.c
@@ -351,3 +351,27 @@ void p6_cpufixup(struct mem_range *mem)
printk_debug("Updating microcode\n");
display_cpuid_update_microcode();
}
+
+
+static
+void p6_enable(struct chip *chip, enum chip_pass pass)
+{
+
+ struct cpu_p6_config *conf = (struct cpu_p6_config *)chip->chip_info;
+
+ switch (pass) {
+ case CONF_PASS_PRE_CONSOLE:
+ break;
+ case CONF_PASS_PRE_PCI:
+ init_timer();
+ break;
+ default:
+ /* nothing yet */
+ break;
+ }
+}
+
+struct chip_control cpu_p6_control = {
+ .enable = p6_enable,
+ .name = "Intel P6 CPU",
+};
diff --git a/src/cpu/p6/disable_mmx_sse.inc b/src/cpu/p6/disable_mmx_sse.inc
new file mode 100644
index 0000000000..5ce9dfdc1f
--- /dev/null
+++ b/src/cpu/p6/disable_mmx_sse.inc
@@ -0,0 +1,27 @@
+ /* Clear out an mmx state */
+ emms
+
+ /*
+ * Put the processor back into a reset state
+ * with respect to the xmm registers.
+ */
+
+ pxor %xmm0, %xmm0
+ pxor %xmm1, %xmm1
+ pxor %xmm2, %xmm2
+ pxor %xmm3, %xmm3
+ pxor %xmm4, %xmm4
+ pxor %xmm5, %xmm5
+ pxor %xmm6, %xmm6
+ pxor %xmm7, %xmm7
+
+ /* Disable floating point emulation */
+ movl %cr0, %eax
+ andl $~(1<<2), %eax
+ movl %eax, %cr0
+
+ /* Disable sse instructions */
+ movl %cr4, %eax
+ andl $~(3<<9), %eax
+ movl %eax, %cr4
+
diff --git a/src/cpu/p6/enable_mmx_sse.inc b/src/cpu/p6/enable_mmx_sse.inc
new file mode 100644
index 0000000000..f0b2487b8c
--- /dev/null
+++ b/src/cpu/p6/enable_mmx_sse.inc
@@ -0,0 +1,25 @@
+ /* Save the BIST result */
+ movl %eax, %ebp
+
+ /*
+ * Enabling mmx registers is a noop
+ * Enable the use of the xmm registers
+ */
+
+ /* Enable sse instructions */
+ movl %cr4, %eax
+ orl $(1<<9), %eax
+ movl %eax, %cr4
+
+ /* Disable floating point emulation */
+ movl %cr0, %eax
+ andl $~(1<<2), %eax
+ movl %eax, %cr0
+
+ /* enable sse extension */
+ movl %cr0, %eax
+ andl $~(1<<1), %eax
+ movl %eax, %cr0
+
+ /* Restore the BIST result */
+ movl %ebp, %eax