-
Notifications
You must be signed in to change notification settings - Fork 99
Expand file tree
/
Copy pathsmp.asm
More file actions
140 lines (115 loc) · 3.12 KB
/
smp.asm
File metadata and controls
140 lines (115 loc) · 3.12 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
; =============================================================================
; 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
mov edx, [p_BSP] ; Get the BSP APIC ID
mov esi, IM_DetectedCoreIDs ; List of 32-bit APIC IDs
xor eax, eax
xor ecx, ecx
mov cx, [p_cpu_detected]
smp_send_INIT:
cmp cx, 0
je smp_send_INIT_done
lodsd
cmp eax, edx ; Is it the BSP?
je smp_send_INIT_skipcore ; If so, skip
cmp byte [p_x2APIC], 1
je smp_send_INIT_x2APIC
smp_send_INIT_APIC:
; Send 'INIT' IPI to APIC ID in AL
push rcx ; Save counter
shl eax, 24
mov ecx, APIC_ICRH ; Interrupt Command Register (ICR); bits 63-32
call apic_write
mov eax, 0x00004500
mov ecx, APIC_ICRL ; Interrupt Command Register (ICR); bits 31-0
call apic_write
smp_send_INIT_verify:
call apic_read
bt eax, 12 ; Verify that the command completed
jc smp_send_INIT_verify
pop rcx ; Restore counter
jmp smp_send_INIT_APIC_done
smp_send_INIT_x2APIC:
; Send 'INIT' IPI to APIC ID in AL
push rcx ; Save counter
mov ecx, APIC_ICR ; Interrupt Command Register (ICR); bits 63-0
shl rax, 32
mov ax, 0x4500
call apic_write
pop rcx ; Restore counter
smp_send_INIT_APIC_done:
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
lodsd
cmp eax, edx ; Is it the BSP?
je smp_send_SIPI_skipcore
cmp byte [p_x2APIC], 1
je smp_send_SIPI_x2APIC
smp_send_SIPI_APIC:
; Send 'Startup' IPI to destination using vector 0x08 to specify entry-point is at the memory-address 0x00008000
push rcx
shl eax, 24
mov ecx, APIC_ICRH ; Interrupt Command Register (ICR); bits 63-32
call apic_write
mov eax, 0x00004608 ; Vector 0x08
mov ecx, APIC_ICRL ; Interrupt Command Register (ICR); bits 31-0
call apic_write
smp_send_SIPI_verify:
call apic_read
bt eax, 12 ; Verify that the command completed
jc smp_send_SIPI_verify
pop rcx
jmp smp_send_SIPI_APIC_done
smp_send_SIPI_x2APIC:
; Send 'Startup' IPI to destination using vector 0x08 to specify entry-point is at the memory-address 0x00008000
push rcx
mov ecx, APIC_ICR ; Interrupt Command Register (ICR); bits 63-0
shl rax, 32
mov ax, 0x4608 ; Vector 0x08
call apic_write
pop rcx
smp_send_SIPI_APIC_done:
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:
; 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