SMP - BSP halts APs before shutting down
This commit is contained in:
parent
311f145bc7
commit
387e1835d1
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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(;;);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
extern unsigned char cpuid2apicid[CONFIG_MAX_CPUS];
|
||||
|
||||
#define barrier() do { mfence(); } while(0)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __SMP_X86_H__ */
|
||||
|
|
|
@ -374,7 +374,7 @@ PUBLIC void minix_shutdown(timer_t *tp)
|
|||
* monitor again
|
||||
*/
|
||||
if (ncpus > 1)
|
||||
NOT_IMPLEMENTED;
|
||||
smp_shutdown_aps();
|
||||
#endif
|
||||
arch_stop_local_timer();
|
||||
hw_intr_disable_all();
|
||||
|
|
11
kernel/smp.c
11
kernel/smp.c
|
@ -11,7 +11,7 @@ static volatile unsigned ap_cpus_booted;
|
|||
SPINLOCK_DEFINE(big_kernel_lock)
|
||||
SPINLOCK_DEFINE(boot_lock)
|
||||
|
||||
void wait_for_APs_to_finish_booting(void)
|
||||
PUBLIC void wait_for_APs_to_finish_booting(void)
|
||||
{
|
||||
/* we must let the other CPUs to run in kernel mode first */
|
||||
BKL_UNLOCK();
|
||||
|
@ -21,7 +21,14 @@ void wait_for_APs_to_finish_booting(void)
|
|||
BKL_LOCK();
|
||||
}
|
||||
|
||||
void ap_boot_finished(unsigned cpu)
|
||||
PUBLIC void ap_boot_finished(unsigned cpu)
|
||||
{
|
||||
ap_cpus_booted++;
|
||||
}
|
||||
|
||||
PUBLIC void smp_ipi_halt_handler(void)
|
||||
{
|
||||
arch_stop_local_timer();
|
||||
arch_smp_halt_cpu();
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,8 @@ SPINLOCK_DECLARE(boot_lock)
|
|||
|
||||
_PROTOTYPE(void wait_for_APs_to_finish_booting, (void));
|
||||
_PROTOTYPE(void ap_boot_finished, (unsigned cpu));
|
||||
_PROTOTYPE(void smp_ipi_halt_handler, (void));
|
||||
_PROTOTYPE(void arch_smp_halt_cpu, (void));
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
|
Loading…
Reference in a new issue