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"
43 return ((reg_read(APIC_ID) >> 24) & 0xff);
48 Apic::disable_external_ints()
50 reg_write(APIC_lvt0, 0x0001003f);
51 reg_write(APIC_lvt1, 0x0001003f);
58 return ((reg_read(APIC_ICR) & 0x00001000) == 0);
63 Apic::mp_ipi_idle_timeout(Cpu const *c, Unsigned32 wait)
65 Unsigned64 wait_till = c->time_us() + wait;
66 while (!mp_ipi_idle() && c->time_us() < wait_till)
71 PUBLIC static inline NEEDS [<cassert>]
73 Apic::mp_send_ipi(Unsigned32 dest, Unsigned32 vect,
74 Unsigned32 mode = APIC_IPI_FIXED)
78 assert((dest & 0x00f3ffff) == 0);
81 while (!mp_ipi_idle())
84 // Set destination for no-shorthand destination type
85 if ((dest & APIC_IPI_DSTMSK) == APIC_IPI_NOSHRT)
87 tmp_val = reg_read(APIC_ICR2);
88 tmp_val &= 0x00ffffff;
89 tmp_val |= dest & 0xff000000;
90 reg_write(APIC_ICR2, tmp_val);
93 // send the interrupt vector to the destination...
94 tmp_val = reg_read(APIC_ICR);
95 tmp_val &= 0xfff32000;
96 tmp_val |= (dest & 0x000c0000) |
97 ( 0x00004000) | // phys proc num, edge triggered, assert
100 reg_write(APIC_ICR, tmp_val);
107 reg_write(APIC_eoi, 0);
116 // set some interrupt vectors to appropriate values
119 // initialize APIC_spiv register
122 // initialize task-priority register
125 disable_external_ints();
127 // get timer going on this CPU
133 Apic::mp_startup(Cpu const *current_cpu, Unsigned32 dest, Address tramp_page)
135 assert((tramp_page & 0xfff00fff) == 0);
137 // XXX: should check for the apic version what to do exactly
138 // XXX: should check for some errors after sending ipi
141 mp_send_ipi(dest, 0, APIC_IPI_INIT);
143 // delay for 10ms (=10,000us)
144 if (!mp_ipi_idle_timeout(current_cpu, 10000))
148 mp_send_ipi(dest, tramp_page >> 12, APIC_IPI_STRTUP);
151 if (!mp_ipi_idle_timeout(current_cpu, 200))
155 mp_send_ipi(dest, tramp_page >> 12, APIC_IPI_STRTUP);
158 if (!mp_ipi_idle_timeout(current_cpu, 200))