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)
|
PUBLIC unsigned int apicid(void)
|
||||||
{
|
{
|
||||||
return lapic_read(LAPIC_ID);
|
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_halt_intr, (void));
|
||||||
|
|
||||||
_PROTOTYPE(void apic_ipi_sched_handler, (void));
|
_PROTOTYPE(void apic_ipi_sched_handler, (void));
|
||||||
_PROTOTYPE(void apic_ipi_halt_handler, (void));
|
|
||||||
|
|
||||||
#define APIC_IPI_DEST 0
|
#define APIC_IPI_DEST 0
|
||||||
#define APIC_IPI_SELF 1
|
#define APIC_IPI_SELF 1
|
||||||
|
@ -73,7 +73,7 @@ ENTRY(apic_ipi_sched_intr)
|
|||||||
lapic_intr(_C_LABEL(apic_ipi_sched_handler))
|
lapic_intr(_C_LABEL(apic_ipi_sched_handler))
|
||||||
|
|
||||||
ENTRY(apic_ipi_halt_intr)
|
ENTRY(apic_ipi_halt_intr)
|
||||||
lapic_intr(_C_LABEL(apic_ipi_halt_handler))
|
lapic_intr(_C_LABEL(smp_ipi_halt_handler))
|
||||||
|
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ extern u32_t busclock[CONFIG_MAX_CPUS];
|
|||||||
extern int panicking;
|
extern int panicking;
|
||||||
|
|
||||||
static int ap_cpu_ready;
|
static int ap_cpu_ready;
|
||||||
|
static int cpu_down;
|
||||||
|
|
||||||
/* there can be at most 255 local APIC ids, each fits in 8 bits */
|
/* there can be at most 255 local APIC ids, each fits in 8 bits */
|
||||||
PRIVATE unsigned char apicid2cpuid[255];
|
PRIVATE unsigned char apicid2cpuid[255];
|
||||||
@ -170,30 +171,30 @@ PUBLIC void smp_halt_cpu (void)
|
|||||||
NOT_IMPLEMENTED;
|
NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
PUBLIC void smp_shutdown_aps (void)
|
PUBLIC void smp_shutdown_aps(void)
|
||||||
{
|
{
|
||||||
u8_t cpu;
|
unsigned cpu;
|
||||||
unsigned aid = apicid();
|
unsigned aid = apicid();
|
||||||
|
unsigned local_cpu = cpuid;
|
||||||
|
|
||||||
if (ncpus == 1)
|
if (ncpus == 1)
|
||||||
goto exit_shutdown_aps;
|
goto exit_shutdown_aps;
|
||||||
|
|
||||||
|
/* we must let the other cpus enter the kernel mode */
|
||||||
|
BKL_UNLOCK();
|
||||||
|
|
||||||
for (cpu = 0; cpu < ncpus; cpu++) {
|
for (cpu = 0; cpu < ncpus; cpu++) {
|
||||||
u16_t i;
|
if (cpu == cpuid)
|
||||||
if (!cpu_is_ready(cpu))
|
|
||||||
continue;
|
|
||||||
if ((aid == cpuid2apicid[cpu]) && (aid == bsp_lapic_id))
|
|
||||||
continue;
|
continue;
|
||||||
|
cpu_down = -1;
|
||||||
|
barrier();
|
||||||
apic_send_ipi(APIC_SMP_CPU_HALT_VECTOR, cpu, APIC_IPI_DEST);
|
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:
|
exit_shutdown_aps:
|
||||||
ioapic_disable_all();
|
ioapic_disable_all();
|
||||||
|
|
||||||
@ -342,3 +343,13 @@ uniproc_fallback:
|
|||||||
intr_init (INTS_MINIX, 0); /* no auto eoi */
|
intr_init (INTS_MINIX, 0); /* no auto eoi */
|
||||||
printf("WARNING : SMP initialization failed\n");
|
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];
|
extern unsigned char cpuid2apicid[CONFIG_MAX_CPUS];
|
||||||
|
|
||||||
|
#define barrier() do { mfence(); } while(0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __SMP_X86_H__ */
|
#endif /* __SMP_X86_H__ */
|
||||||
|
@ -374,7 +374,7 @@ PUBLIC void minix_shutdown(timer_t *tp)
|
|||||||
* monitor again
|
* monitor again
|
||||||
*/
|
*/
|
||||||
if (ncpus > 1)
|
if (ncpus > 1)
|
||||||
NOT_IMPLEMENTED;
|
smp_shutdown_aps();
|
||||||
#endif
|
#endif
|
||||||
arch_stop_local_timer();
|
arch_stop_local_timer();
|
||||||
hw_intr_disable_all();
|
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(big_kernel_lock)
|
||||||
SPINLOCK_DEFINE(boot_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 */
|
/* we must let the other CPUs to run in kernel mode first */
|
||||||
BKL_UNLOCK();
|
BKL_UNLOCK();
|
||||||
@ -21,7 +21,14 @@ void wait_for_APs_to_finish_booting(void)
|
|||||||
BKL_LOCK();
|
BKL_LOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ap_boot_finished(unsigned cpu)
|
PUBLIC void ap_boot_finished(unsigned cpu)
|
||||||
{
|
{
|
||||||
ap_cpus_booted++;
|
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 wait_for_APs_to_finish_booting, (void));
|
||||||
_PROTOTYPE(void ap_boot_finished, (unsigned cpu));
|
_PROTOTYPE(void ap_boot_finished, (unsigned cpu));
|
||||||
|
_PROTOTYPE(void smp_ipi_halt_handler, (void));
|
||||||
|
_PROTOTYPE(void arch_smp_halt_cpu, (void));
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user