File indexing completed on 2025-05-11 08:24:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <rtems/score/smpimpl.h>
0037
0038 #include <apic.h>
0039 #include <assert.h>
0040 #include <bsp.h>
0041 #include <smp.h>
0042 #include <libcpu/page.h>
0043 #include <rtems/score/idt.h>
0044
0045 #include <string.h>
0046
0047 extern void _Trampoline_start(void);
0048 extern const uint64_t _Trampoline_size;
0049
0050 static bool has_ap_started = false;
0051
0052
0053
0054
0055
0056
0057
0058 static void copy_trampoline(void)
0059 {
0060
0061 void* trampoline_dest = (void*) TRAMPOLINE_ADDR;
0062 memcpy(trampoline_dest, (void*) _Trampoline_start, _Trampoline_size);
0063 }
0064
0065
0066
0067
0068
0069
0070
0071
0072 static bool wait_for_ap(uint32_t timeout_ms)
0073 {
0074 uint8_t chan2_value;
0075 uint32_t pit_ticks = PIT_FREQUENCY/1000;
0076
0077 PIT_CHAN2_ENABLE(chan2_value);
0078 PIT_CHAN2_WRITE_TICKS(pit_ticks);
0079
0080 for (int i = 0; has_ap_started == false && i < timeout_ms; i++) {
0081 PIT_CHAN2_START_DELAY(chan2_value);
0082 PIT_CHAN2_WAIT_DELAY(pit_ticks);
0083 amd64_spinwait();
0084 }
0085
0086 return has_ap_started;
0087 }
0088
0089 static void bsp_inter_processor_interrupt(void* arg)
0090 {
0091 _SMP_Inter_processor_interrupt_handler(_Per_CPU_Get());
0092 lapic_eoi();
0093 }
0094
0095 void _CPU_SMP_Prepare_start_multitasking(void)
0096 {
0097
0098 }
0099
0100 bool _CPU_SMP_Start_processor(uint32_t cpu_index)
0101 {
0102 has_ap_started = false;
0103 lapic_start_ap(cpu_index, TRAMPOLINE_PAGE_VECTOR);
0104 return wait_for_ap(WAIT_FOR_AP_TIMEOUT_MS);
0105 }
0106
0107 uint32_t _CPU_SMP_Get_current_processor(void)
0108 {
0109 uint8_t lapic_id = lapic_get_id();
0110 return amd64_lapic_to_cpu_map[lapic_id];
0111 }
0112
0113 uint32_t _CPU_SMP_Initialize(void)
0114 {
0115 copy_trampoline();
0116 return lapic_get_num_of_procesors();
0117 }
0118
0119 void _CPU_SMP_Finalize_initialization(uint32_t cpu_count)
0120 {
0121 rtems_status_code sc = rtems_interrupt_handler_install(
0122 BSP_VECTOR_IPI,
0123 "IPI",
0124 RTEMS_INTERRUPT_UNIQUE,
0125 bsp_inter_processor_interrupt,
0126 NULL
0127 );
0128 assert(sc == RTEMS_SUCCESSFUL);
0129 }
0130
0131 void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
0132 {
0133 lapic_send_ipi(target_processor_index, BSP_VECTOR_IPI);
0134 }
0135
0136 void smp_init_ap(void)
0137 {
0138 has_ap_started = true;
0139
0140 Context_Control_fp* null_fp_context_p = &_CPU_Null_fp_context;
0141 _CPU_Context_restore_fp(&null_fp_context_p);
0142
0143 amd64_lapic_base[LAPIC_REGISTER_SPURIOUS] =
0144 LAPIC_SPURIOUS_ENABLE | BSP_VECTOR_SPURIOUS;
0145
0146 lidt(&amd64_idtr);
0147
0148 _SMP_Start_multitasking_on_secondary_processor(_Per_CPU_Get());
0149 }