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>
14 #include <cpu/l2_cache.h>
17 #if CONFIG_SMP || CONFIG_IOAPIC
22 static void cache_on(struct mem_range *mem)
25 printk_info("Enabling cache...");
28 /* we need an #ifdef i586 here at some point ... */
29 __asm__ __volatile__("mov %cr0, %eax\n\t"
30 "and $0x9fffffff,%eax\n\t"
31 "mov %eax, %cr0\n\t");
32 /* turns out cache isn't really on until you set MTRR registers on
34 * NOTHING FANCY. Linux does a much better job anyway.
35 * so absolute minimum needed to get it going.
37 /* OK, linux it turns out does nothing. We have to do it ... */
39 // totalram here is in linux sizing, i.e. units of KB.
40 // set_mtrr is responsible for getting it into the right units!
45 printk_info("done.\n");
48 static void interrupts_on()
50 /* this is so interrupts work. This is very limited scope --
51 * linux will do better later, we hope ...
53 /* this is the first way we learned to do it. It fails on real SMP
54 * stuff. So we have to do things differently ...
55 * see the Intel mp1.4 spec, page A-3
59 /* Only Pentium Pro and later have those MSR stuff */
62 printk_info("Setting up local apic...");
64 /* Enable the local apic */
65 msr = rdmsr(APIC_BASE_MSR);
66 msr.lo |= APIC_BASE_MSR_ENABLE;
67 msr.lo &= ~APIC_BASE_MSR_ADDR_MASK;
68 msr.lo |= APIC_DEFAULT_BASE;
69 wrmsr(APIC_BASE_MSR, msr);
72 * Set Task Priority to 'accept all'.
74 apic_write_around(APIC_TASKPRI,
75 apic_read_around(APIC_TASKPRI) & ~APIC_TPRI_MASK);
77 /* Put the local apic in virtual wire mode */
78 apic_write_around(APIC_SPIV,
79 (apic_read_around(APIC_SPIV) & ~(APIC_VECTOR_MASK))
81 apic_write_around(APIC_LVT0,
82 (apic_read_around(APIC_LVT0) &
83 ~(APIC_LVT_MASKED | APIC_LVT_LEVEL_TRIGGER |
84 APIC_LVT_REMOTE_IRR | APIC_INPUT_POLARITY |
85 APIC_SEND_PENDING |APIC_LVT_RESERVED_1 |
86 APIC_DELIVERY_MODE_MASK))
87 | (APIC_LVT_REMOTE_IRR |APIC_SEND_PENDING |
88 APIC_DELIVERY_MODE_EXTINT)
90 apic_write_around(APIC_LVT1,
91 (apic_read_around(APIC_LVT1) &
92 ~(APIC_LVT_MASKED | APIC_LVT_LEVEL_TRIGGER |
93 APIC_LVT_REMOTE_IRR | APIC_INPUT_POLARITY |
94 APIC_SEND_PENDING |APIC_LVT_RESERVED_1 |
95 APIC_DELIVERY_MODE_MASK))
96 | (APIC_LVT_REMOTE_IRR |APIC_SEND_PENDING |
97 APIC_DELIVERY_MODE_NMI)
100 printk_debug(" apic_id: %d ",
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 /* some cpus need a fixup done. This is the hook for doing that. */
132 /* Turn on caching if we haven't already */
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();
146 processor_id = this_processors_id();
147 printk_info("CPU #%d Initialized\n", processor_id);