SMP - BSP halts APs before shutting down

This commit is contained in:
Tomas Hruby
2010-09-15 14:10:54 +00:00
parent 311f145bc7
commit 387e1835d1
8 changed files with 39 additions and 22 deletions

View File

@@ -398,10 +398,6 @@ PUBLIC void apic_ipi_sched_handler(void)
{
}
PUBLIC void apic_ipi_halt_handler(void)
{
}
PUBLIC unsigned int apicid(void)
{
return lapic_read(LAPIC_ID);

View File

@@ -167,7 +167,6 @@ _PROTOTYPE(void apic_ipi_sched_intr, (void));
_PROTOTYPE(void apic_ipi_halt_intr, (void));
_PROTOTYPE(void apic_ipi_sched_handler, (void));
_PROTOTYPE(void apic_ipi_halt_handler, (void));
#define APIC_IPI_DEST 0
#define APIC_IPI_SELF 1

View File

@@ -73,7 +73,7 @@ ENTRY(apic_ipi_sched_intr)
lapic_intr(_C_LABEL(apic_ipi_sched_handler))
ENTRY(apic_ipi_halt_intr)
lapic_intr(_C_LABEL(apic_ipi_halt_handler))
lapic_intr(_C_LABEL(smp_ipi_halt_handler))
#endif /* CONFIG_SMP */

View File

@@ -37,6 +37,7 @@ extern u32_t busclock[CONFIG_MAX_CPUS];
extern int panicking;
static int ap_cpu_ready;
static int cpu_down;
/* there can be at most 255 local APIC ids, each fits in 8 bits */
PRIVATE unsigned char apicid2cpuid[255];
@@ -170,30 +171,30 @@ PUBLIC void smp_halt_cpu (void)
NOT_IMPLEMENTED;
}
PUBLIC void smp_shutdown_aps (void)
PUBLIC void smp_shutdown_aps(void)
{
u8_t cpu;
unsigned cpu;
unsigned aid = apicid();
unsigned local_cpu = cpuid;
if (ncpus == 1)
goto exit_shutdown_aps;
/* we must let the other cpus enter the kernel mode */
BKL_UNLOCK();
for (cpu = 0; cpu < ncpus; cpu++) {
u16_t i;
if (!cpu_is_ready(cpu))
continue;
if ((aid == cpuid2apicid[cpu]) && (aid == bsp_lapic_id))
if (cpu == cpuid)
continue;
cpu_down = -1;
barrier();
apic_send_ipi(APIC_SMP_CPU_HALT_VECTOR, cpu, APIC_IPI_DEST);
/* TODO wait for the cpu to be down */
/* wait for the cpu to be down */
while (cpu_down != cpu);
printf("CPU %d is down\n", cpu);
cpu_clear_flag(cpu, CPU_IS_READY);
}
/* Sending INIT to a processor makes it to wait in a halt state */
for (cpu = 0; cpu < ncpus; cpu++) {
if ((aid == cpuid2apicid[cpu]) && (aid == bsp_lapic_id))
continue;
apic_send_init_ipi (cpu, 0);
}
exit_shutdown_aps:
ioapic_disable_all();
@@ -342,3 +343,13 @@ uniproc_fallback:
intr_init (INTS_MINIX, 0); /* no auto eoi */
printf("WARNING : SMP initialization failed\n");
}
PUBLIC void arch_smp_halt_cpu(void)
{
/* say that we are down */
cpu_down = cpuid;
barrier();
/* unlock the BKL and don't continue */
BKL_UNLOCK();
for(;;);
}

View File

@@ -23,6 +23,8 @@
extern unsigned char cpuid2apicid[CONFIG_MAX_CPUS];
#define barrier() do { mfence(); } while(0)
#endif
#endif /* __SMP_X86_H__ */