-
Notifications
You must be signed in to change notification settings - Fork 99
Expand file tree
/
Copy pathsmp.asm
More file actions
116 lines (96 loc) · 2.87 KB
/
smp.asm
File metadata and controls
116 lines (96 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
; =============================================================================
; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems
; Copyright (C) 2008-2025 Return Infinity -- see LICENSE.TXT
;
; INIT SMP
; =============================================================================
init_smp:
; Check if we want the AP's to be enabled.. if not then skip to end
cmp byte [cfg_smpinit], 1 ; Check if SMP should be enabled
jne noMP ; If not then skip SMP init
; Start the AP's one by one
xor eax, eax
xor edx, edx
mov rsi, [p_LocalAPICAddress]
mov eax, [rsi+0x20] ; Add the offset for the APIC ID location
shr rax, 24 ; APIC ID is stored in bits 31:24
mov dl, al ; Store BSP APIC ID in DL
mov esi, IM_DetectedCoreIDs
xor eax, eax
xor ecx, ecx
mov cx, [p_cpu_detected]
smp_send_INIT:
cmp cx, 0
je smp_send_INIT_done
lodsb
cmp al, dl ; Is it the BSP?
je smp_send_INIT_skipcore
; Send 'INIT' IPI to APIC ID in AL
mov rdi, [p_LocalAPICAddress]
shl eax, 24
mov dword [rdi+0x310], eax ; Interrupt Command Register (ICR); bits 63-32
mov eax, 0x00004500
mov dword [rdi+0x300], eax ; Interrupt Command Register (ICR); bits 31-0
smp_send_INIT_verify:
mov eax, [rdi+0x300] ; Interrupt Command Register (ICR); bits 31-0
bt eax, 12 ; Verify that the command completed
jc smp_send_INIT_verify
smp_send_INIT_skipcore:
dec cl
jmp smp_send_INIT
smp_send_INIT_done:
; Wait 500 microseconds
mov eax, 500
call timer_delay
mov esi, IM_DetectedCoreIDs
xor ecx, ecx
mov cx, [p_cpu_detected]
smp_send_SIPI:
cmp cx, 0
je smp_send_SIPI_done
lodsb
cmp al, dl ; Is it the BSP?
je smp_send_SIPI_skipcore
; Send 'Startup' IPI to destination using vector 0x08 to specify entry-point is at the memory-address 0x00008000
mov rdi, [p_LocalAPICAddress]
shl eax, 24
mov dword [rdi+0x310], eax ; Interrupt Command Register (ICR); bits 63-32
mov eax, 0x00004608 ; Vector 0x08
mov dword [rdi+0x300], eax ; Interrupt Command Register (ICR); bits 31-0
smp_send_SIPI_verify:
mov eax, [rdi+0x300] ; Interrupt Command Register (ICR); bits 31-0
bt eax, 12 ; Verify that the command completed
jc smp_send_SIPI_verify
smp_send_SIPI_skipcore:
dec cl
jmp smp_send_SIPI
smp_send_SIPI_done:
; Wait 10000 microseconds for the AP's to finish
mov eax, 10000
call timer_delay
noMP:
; Gather and store the APIC ID of the BSP
xor eax, eax
mov rsi, [p_LocalAPICAddress]
add rsi, 0x20 ; Add the offset for the APIC ID location
lodsd ; APIC ID is stored in bits 31:24
shr rax, 24 ; AL now holds the CPU's APIC ID (0 - 255)
mov [p_BSP], eax ; Store the BSP APIC ID
; Calculate base speed of CPU
cpuid
xor edx, edx
xor eax, eax
rdtsc
push rax
mov rax, 1024
call timer_delay
rdtsc
pop rdx
sub rax, rdx
xor edx, edx
mov rcx, 1024
div rcx
mov [p_cpu_speed], ax
ret
; =============================================================================
; EOF