diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/p6/Config.lb | 7 | ||||
-rw-r--r-- | src/cpu/p6/apic_timer.c | 26 | ||||
-rw-r--r-- | src/cpu/p6/chip.h | 5 | ||||
-rw-r--r-- | src/cpu/p6/cpufixup.c | 24 | ||||
-rw-r--r-- | src/cpu/p6/disable_mmx_sse.inc | 27 | ||||
-rw-r--r-- | src/cpu/p6/enable_mmx_sse.inc | 25 |
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 |