1 #include <console/console.h>
6 #include <cpu/cpufixup.h>
7 #include <smp/start_stop.h>
8 #include <cpu/cpufixup.h>
9 #include <cpu/p6/mtrr.h>
10 #include <cpu/p6/msr.h>
11 #include <cpu/p6/apic.h>
12 #include <cpu/p5/cpuid.h>
13 #include <arch/smp/lapic.h>
15 #include <cpu/l2_cache.h>
18 #if CONFIG_SMP || CONFIG_IOAPIC
23 static void cache_on(struct mem_range *mem)
26 printk_info("Enabling cache...");
29 /* we need an #ifdef i586 here at some point ... */
30 __asm__ __volatile__("mov %cr0, %eax\n\t"
31 "and $0x9fffffff,%eax\n\t"
32 "mov %eax, %cr0\n\t");
33 /* turns out cache isn't really on until you set MTRR registers on
35 * NOTHING FANCY. Linux does a much better job anyway.
36 * so absolute minimum needed to get it going.
38 /* OK, linux it turns out does nothing. We have to do it ... */
40 // totalram here is in linux sizing, i.e. units of KB.
41 // set_mtrr is responsible for getting it into the right units!
46 printk_info("done.\n");
49 static void interrupts_on()
51 /* this is so interrupts work. This is very limited scope --
52 * linux will do better later, we hope ...
54 /* this is the first way we learned to do it. It fails on real SMP
55 * stuff. So we have to do things differently ...
56 * see the Intel mp1.4 spec, page A-3
60 /* Only Pentium Pro and later have those MSR stuff */
63 printk_info("Setting up local apic...");
65 /* Enable the local apic */
66 msr = rdmsr(APIC_BASE_MSR);
67 msr.lo |= APIC_BASE_MSR_ENABLE;
68 msr.lo &= ~APIC_BASE_MSR_ADDR_MASK;
69 msr.lo |= APIC_DEFAULT_BASE;
70 wrmsr(APIC_BASE_MSR, msr);
73 * Set Task Priority to 'accept all'.
75 apic_write_around(APIC_TASKPRI,
76 apic_read_around(APIC_TASKPRI) & ~APIC_TPRI_MASK);
78 /* Put the local apic in virtual wire mode */
79 apic_write_around(APIC_SPIV,
80 (apic_read_around(APIC_SPIV) & ~(APIC_VECTOR_MASK))
82 apic_write_around(APIC_LVT0,
83 (apic_read_around(APIC_LVT0) &
84 ~(APIC_LVT_MASKED | APIC_LVT_LEVEL_TRIGGER |
85 APIC_LVT_REMOTE_IRR | APIC_INPUT_POLARITY |
86 APIC_SEND_PENDING |APIC_LVT_RESERVED_1 |
87 APIC_DELIVERY_MODE_MASK))
88 | (APIC_LVT_REMOTE_IRR |APIC_SEND_PENDING |
89 APIC_DELIVERY_MODE_EXTINT)
91 apic_write_around(APIC_LVT1,
92 (apic_read_around(APIC_LVT1) &
93 ~(APIC_LVT_MASKED | APIC_LVT_LEVEL_TRIGGER |
94 APIC_LVT_REMOTE_IRR | APIC_INPUT_POLARITY |
95 APIC_SEND_PENDING |APIC_LVT_RESERVED_1 |
96 APIC_DELIVERY_MODE_MASK))
97 | (APIC_LVT_REMOTE_IRR |APIC_SEND_PENDING |
98 APIC_DELIVERY_MODE_NMI)
101 printk_debug(" apic_id: %d ", lapicid());
105 /* Only Pentium Pro and later have those MSR stuff */
108 printk_info("Disabling local apic...");
110 msr = rdmsr(APIC_BASE_MSR);
111 msr.lo &= ~APIC_BASE_MSR_ENABLE;
112 wrmsr(APIC_BASE_MSR, msr);
115 printk_info("done.\n");
119 unsigned long cpu_initialize(struct mem_range *mem)
121 /* Because we busy wait at the printk spinlock.
122 * It is important to keep the number of printed messages
123 * from secondary cpus to a minimum, when debugging is
126 unsigned long processor_id = this_processors_id();
127 printk_notice("Initializing CPU #%d\n", processor_id);
129 /* Turn on caching if we haven't already */
135 /* some cpus need a fixup done. This is the hook for doing that. */
139 /* now that everything is really up, enable the l2 cache if desired.
140 * The enable can wait until this point, because linuxbios and it's
141 * data areas are tiny, easily fitting into the L1 cache.
143 configure_l2_cache();
147 processor_id = this_processors_id();
148 printk_info("CPU #%d Initialized\n", processor_id);