62c666566e
- kernel detects CPUs by searching ACPI tables for local apic nodes - each CPU has its own TSS that points to its own stack. All cpus boot on the same boot stack (in sequence) but switch to its private stack as soon as they can. - final booting code in main() placed in bsp_finish_booting() which is executed only after the BSP switches to its final stack - apic functions to send startup interrupts - assembler functions to handle CPU features not needed for single cpu mode like memory barries, HT detection etc. - new files kernel/smp.[ch], kernel/arch/i386/arch_smp.c and kernel/arch/i386/include/arch_smp.h - 16-bit trampoline code for the APs. It is executed by each AP after receiving startup IPIs it brings up the CPUs to 32bit mode and let them spin in an infinite loop so they don't do any damage. - implementation of kernel spinlock - CONFIG_SMP and CONFIG_MAX_CPUS set by the build system
55 lines
1.5 KiB
C
55 lines
1.5 KiB
C
#ifndef __SMP_H__
|
|
#define __SMP_H__
|
|
|
|
#ifdef CONFIG_SMP
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#include "kernel.h"
|
|
#include "arch_smp.h"
|
|
|
|
/* number of CPUs (execution strands in the system */
|
|
EXTERN unsigned ncpus;
|
|
/* Number of virtual strands per physical core */
|
|
EXTERN unsigned ht_per_core;
|
|
/* which cpu is bootstraping */
|
|
EXTERN unsigned bsp_cpu_id;
|
|
|
|
#define cpu_is_bsp(cpu) (bsp_cpu_id == cpu)
|
|
|
|
/*
|
|
* SMP initialization is largely architecture dependent and each architecture
|
|
* must provide a method how to do it. If initiating SMP fails the function does
|
|
* not report it. However it must put the system in such a state that it falls
|
|
* back to a uniprocessor system. Although the uniprocessor configuration may be
|
|
* suboptimal, the system must be able to run on the bootstrap processor as if
|
|
* it was the only processor in the system
|
|
*/
|
|
_PROTOTYPE(void smp_init, (void));
|
|
|
|
_PROTOTYPE(void smp_ipi_err_int, (void));
|
|
_PROTOTYPE(void smp_ipi_spv_int, (void));
|
|
_PROTOTYPE(void smp_ipi_sched, (void));
|
|
_PROTOTYPE(void smp_ipi_dequeue, (void));
|
|
_PROTOTYPE(void smp_ipi_stop, (void));
|
|
_PROTOTYPE(void smp_ipi_reboot, (void));
|
|
|
|
#define CPU_IS_BSP 1
|
|
#define CPU_IS_READY 2
|
|
|
|
struct cpu {
|
|
u32_t flags;
|
|
};
|
|
|
|
EXTERN struct cpu cpus[CONFIG_MAX_CPUS];
|
|
|
|
#define cpu_set_flag(cpu, flag) do { cpus[cpu].flags |= (flag); } while(0)
|
|
#define cpu_clear_flag(cpu, flag) do { cpus[cpu].flags &= ~(flag); } while(0)
|
|
#define cpu_test_flag(cpu, flag) (cpus[cpu].flags & (flag))
|
|
#define cpu_is_ready(cpu) cpu_test_flag(cpu, CPU_IS_READY)
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#endif /* CONFIG_SMP */
|
|
|
|
#endif /* __SMP_H__ */
|