8 APIC_IPI_NOSHRT = 0x00000000,
9 APIC_IPI_SELF = 0x00040000,
10 APIC_IPI_ALL = 0x00080000,
11 APIC_IPI_OTHERS = 0x000c0000,
12 APIC_IPI_DSTMSK = 0x000c0000
17 APIC_IPI_FIXED = 0x00000000,
18 APIC_IPI_NMI = 0x00000400,
19 APIC_IPI_INIT = 0x00000500,
20 APIC_IPI_STRTUP = 0x00000600
37 #include "processor.h"
41 Apic::disable_external_ints()
43 reg_write(APIC_lvt0, 0x0001003f);
44 reg_write(APIC_lvt1, 0x0001003f);
51 return ((reg_read(APIC_ICR) & 0x00001000) == 0);
56 Apic::mp_ipi_idle_timeout(Cpu const *c, Unsigned32 wait)
58 Unsigned64 wait_till = c->time_us() + wait;
59 while (!mp_ipi_idle() && c->time_us() < wait_till)
66 Apic::delay(Cpu const *c, Unsigned32 wait)
68 Unsigned64 wait_till = c->time_us() + wait;
69 while (c->time_us() < wait_till)
73 PUBLIC static inline NEEDS [<cassert>]
75 Apic::mp_send_ipi(Unsigned32 dest, Unsigned32 vect,
76 Unsigned32 mode = APIC_IPI_FIXED)
80 assert((dest & 0x00f3ffff) == 0);
83 while (!mp_ipi_idle())
86 // Set destination for no-shorthand destination type
87 if ((dest & APIC_IPI_DSTMSK) == APIC_IPI_NOSHRT)
89 tmp_val = reg_read(APIC_ICR2);
90 tmp_val &= 0x00ffffff;
91 tmp_val |= dest & 0xff000000;
92 reg_write(APIC_ICR2, tmp_val);
95 // send the interrupt vector to the destination...
96 tmp_val = reg_read(APIC_ICR);
97 tmp_val &= 0xfff32000;
98 tmp_val |= (dest & 0x000c0000) |
99 ( 0x00004000) | // phys proc num, edge triggered, assert
100 (mode & 0x00000700) |
102 reg_write(APIC_ICR, tmp_val);
109 reg_write(APIC_eoi, 0);
118 // set some interrupt vectors to appropriate values
121 // initialize APIC_spiv register
124 // initialize task-priority register
127 disable_external_ints();
129 // get timer going on this CPU
130 timer_set_divisor(1);
136 Apic::mp_startup(Cpu const *current_cpu, Unsigned32 dest, Address tramp_page)
138 assert((tramp_page & 0xfff00fff) == 0);
140 // XXX: should check for the apic version what to do exactly
141 // XXX: should check for some errors after sending ipi
144 mp_send_ipi(dest, 0, APIC_IPI_INIT);
146 delay(current_cpu, 200);
148 // delay for 10ms (=10,000us)
149 if (!mp_ipi_idle_timeout(current_cpu, 10000))
153 mp_send_ipi(dest, tramp_page >> 12, APIC_IPI_STRTUP);
156 if (!mp_ipi_idle_timeout(current_cpu, 200))
160 mp_send_ipi(dest, tramp_page >> 12, APIC_IPI_STRTUP);
163 if (!mp_ipi_idle_timeout(current_cpu, 200))