Rev 7129 | Rev 7734 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7129 | Rev 7132 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; Shutdown for Menuet ;; |
6 | ;; Shutdown for Menuet ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Distributed under General Public License ;; |
8 | ;; Distributed under General Public License ;; |
9 | ;; See file COPYING for details. ;; |
9 | ;; See file COPYING for details. ;; |
10 | ;; Copyright 2003 Ville Turjanmaa ;; |
10 | ;; Copyright 2003 Ville Turjanmaa ;; |
11 | ;; ;; |
11 | ;; ;; |
12 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
12 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
13 | 13 | ||
14 | $Revision: 7129 $ |
14 | $Revision: 7132 $ |
15 | 15 | ||
16 | align 4 |
16 | align 4 |
17 | system_shutdown: ; shut down the system |
17 | system_shutdown: ; shut down the system |
18 | 18 | ||
19 | cmp byte [BOOT_VARS+BOOT_SHUTDOWN_TYPE], SYSTEM_SHUTDOWN |
19 | cmp byte [BOOT.shutdown_type], SYSTEM_SHUTDOWN |
20 | jb @F |
20 | jb @F |
21 | cmp byte [BOOT_VARS+BOOT_SHUTDOWN_TYPE], SYSTEM_RESTART |
21 | cmp byte [BOOT.shutdown_type], SYSTEM_RESTART |
22 | jbe .valid |
22 | jbe .valid |
23 | @@: |
23 | @@: |
24 | ret |
24 | ret |
25 | .valid: |
25 | .valid: |
26 | call stop_all_services |
26 | call stop_all_services |
27 | 27 | ||
28 | yes_shutdown_param: |
28 | yes_shutdown_param: |
29 | ; Shutdown other CPUs, if initialized |
29 | ; Shutdown other CPUs, if initialized |
30 | cmp [ap_initialized], 0 |
30 | cmp [ap_initialized], 0 |
31 | jz .no_shutdown_cpus |
31 | jz .no_shutdown_cpus |
32 | mov edi, [LAPIC_BASE] |
32 | mov edi, [LAPIC_BASE] |
33 | add edi, 300h |
33 | add edi, 300h |
34 | mov esi, smpt+4 |
34 | mov esi, smpt+4 |
35 | mov ebx, [cpu_count] |
35 | mov ebx, [cpu_count] |
36 | dec ebx |
36 | dec ebx |
37 | .shutdown_cpus_loop: |
37 | .shutdown_cpus_loop: |
38 | lodsd |
38 | lodsd |
39 | push esi |
39 | push esi |
40 | xor esi, esi |
40 | xor esi, esi |
41 | inc esi |
41 | inc esi |
42 | shl eax, 24 |
42 | shl eax, 24 |
43 | mov [edi+10h], eax |
43 | mov [edi+10h], eax |
44 | ; assert INIT IPI |
44 | ; assert INIT IPI |
45 | mov dword [edi], 0C500h |
45 | mov dword [edi], 0C500h |
46 | call delay_ms |
46 | call delay_ms |
47 | @@: |
47 | @@: |
48 | test dword [edi], 1000h |
48 | test dword [edi], 1000h |
49 | jnz @b |
49 | jnz @b |
50 | ; deassert INIT IPI |
50 | ; deassert INIT IPI |
51 | mov dword [edi], 8500h |
51 | mov dword [edi], 8500h |
52 | call delay_ms |
52 | call delay_ms |
53 | @@: |
53 | @@: |
54 | test dword [edi], 1000h |
54 | test dword [edi], 1000h |
55 | jnz @b |
55 | jnz @b |
56 | ; don't send STARTUP IPI: let other CPUs be in wait-for-startup state |
56 | ; don't send STARTUP IPI: let other CPUs be in wait-for-startup state |
57 | pop esi |
57 | pop esi |
58 | dec ebx |
58 | dec ebx |
59 | jnz .shutdown_cpus_loop |
59 | jnz .shutdown_cpus_loop |
60 | .no_shutdown_cpus: |
60 | .no_shutdown_cpus: |
61 | 61 | ||
62 | cli |
62 | cli |
63 | call IRQ_mask_all |
63 | call IRQ_mask_all |
64 | 64 | ||
65 | mov eax, [OS_BASE + BOOT_SHUTDOWN_TYPE] |
65 | mov eax, dword[BOOT.shutdown_type] |
66 | cmp al, SYSTEM_RESTART |
66 | cmp al, SYSTEM_RESTART |
67 | jne @F |
67 | jne @F |
68 | 68 | ||
69 | ; load kernel.mnt to _CLEAN_ZONE |
69 | ; load kernel.mnt to _CLEAN_ZONE |
70 | mov ebx, kernel_file_load |
70 | mov ebx, kernel_file_load |
71 | pushad |
71 | pushad |
72 | call file_system_lfn |
72 | call file_system_lfn |
73 | popad |
73 | popad |
74 | @@: |
74 | @@: |
75 | mov esi, OS_BASE+restart_code_start ; move kernel re-starter to 0x5000:0 |
75 | mov esi, OS_BASE+restart_code_start ; move kernel re-starter to 0x5000:0 |
76 | mov edi, OS_BASE+0x50000 |
76 | mov edi, OS_BASE+0x50000 |
77 | mov ecx, (restart_code_end - restart_code_start)/4 |
77 | mov ecx, (restart_code_end - restart_code_start)/4 |
78 | rep movsd |
78 | rep movsd |
79 | 79 | ||
80 | call create_trampoline_pgmap |
80 | call create_trampoline_pgmap |
81 | mov cr3, eax |
81 | mov cr3, eax |
82 | jmp @F |
82 | jmp @F |
83 | org $-OS_BASE |
83 | org $-OS_BASE |
84 | @@: |
84 | @@: |
85 | 85 | ||
86 | ;disable paging |
86 | ;disable paging |
87 | 87 | ||
88 | mov eax, cr0 |
88 | mov eax, cr0 |
89 | and eax, 0x7FFFFFFF |
89 | and eax, 0x7FFFFFFF |
90 | mov cr0, eax |
90 | mov cr0, eax |
91 | mov eax, cr3 |
91 | mov eax, cr3 |
92 | mov cr3, eax |
92 | mov cr3, eax |
93 | 93 | ||
94 | cmp byte [BOOT_SHUTDOWN_TYPE], SYSTEM_SHUTDOWN |
94 | cmp byte [BOOT_LO.shutdown_type], SYSTEM_SHUTDOWN |
95 | jne no_acpi_power_off |
95 | jne no_acpi_power_off |
96 | 96 | ||
97 | ; system_power_off |
97 | ; system_power_off |
98 | 98 | ||
99 | mov ebx, [acpi_fadt_base-OS_BASE] |
99 | mov ebx, [acpi_fadt_base-OS_BASE] |
100 | cmp dword [ebx], 'FACP' |
100 | cmp dword [ebx], 'FACP' |
101 | jne no_acpi_power_off |
101 | jne no_acpi_power_off |
102 | mov esi, [acpi_dsdt_base-OS_BASE] |
102 | mov esi, [acpi_dsdt_base-OS_BASE] |
103 | cmp dword [esi], 'DSDT' |
103 | cmp dword [esi], 'DSDT' |
104 | jne no_acpi_power_off |
104 | jne no_acpi_power_off |
105 | mov eax, [esi+4] ; DSDT length |
105 | mov eax, [esi+4] ; DSDT length |
106 | sub eax, 36+4 |
106 | sub eax, 36+4 |
107 | jbe no_acpi_power_off |
107 | jbe no_acpi_power_off |
108 | add esi, 36 |
108 | add esi, 36 |
109 | .scan_dsdt: |
109 | .scan_dsdt: |
110 | cmp dword [esi], '_S5_' |
110 | cmp dword [esi], '_S5_' |
111 | jnz .scan_dsdt_cont |
111 | jnz .scan_dsdt_cont |
112 | cmp byte [esi+4], 12h ; DefPackage opcode |
112 | cmp byte [esi+4], 12h ; DefPackage opcode |
113 | jnz .scan_dsdt_cont |
113 | jnz .scan_dsdt_cont |
114 | mov dl, [esi+6] |
114 | mov dl, [esi+6] |
115 | cmp dl, 4 ; _S5_ package must contain 4 bytes |
115 | cmp dl, 4 ; _S5_ package must contain 4 bytes |
116 | ; ...in theory; in practice, VirtualBox has 2 bytes |
116 | ; ...in theory; in practice, VirtualBox has 2 bytes |
117 | ja .scan_dsdt_cont |
117 | ja .scan_dsdt_cont |
118 | cmp dl, 1 |
118 | cmp dl, 1 |
119 | jb .scan_dsdt_cont |
119 | jb .scan_dsdt_cont |
120 | lea esi, [esi+7] |
120 | lea esi, [esi+7] |
121 | xor ecx, ecx |
121 | xor ecx, ecx |
122 | cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx |
122 | cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx |
123 | jz @f |
123 | jz @f |
124 | cmp byte [esi], 0xA |
124 | cmp byte [esi], 0xA |
125 | jnz no_acpi_power_off |
125 | jnz no_acpi_power_off |
126 | inc esi |
126 | inc esi |
127 | mov cl, [esi] |
127 | mov cl, [esi] |
128 | @@: |
128 | @@: |
129 | inc esi |
129 | inc esi |
130 | cmp dl, 2 |
130 | cmp dl, 2 |
131 | jb @f |
131 | jb @f |
132 | cmp byte [esi], 0 |
132 | cmp byte [esi], 0 |
133 | jz @f |
133 | jz @f |
134 | cmp byte [esi], 0xA |
134 | cmp byte [esi], 0xA |
135 | jnz no_acpi_power_off |
135 | jnz no_acpi_power_off |
136 | inc esi |
136 | inc esi |
137 | mov ch, [esi] |
137 | mov ch, [esi] |
138 | @@: |
138 | @@: |
139 | jmp do_acpi_power_off |
139 | jmp do_acpi_power_off |
140 | .scan_dsdt_cont: |
140 | .scan_dsdt_cont: |
141 | inc esi |
141 | inc esi |
142 | dec eax |
142 | dec eax |
143 | jnz .scan_dsdt |
143 | jnz .scan_dsdt |
144 | jmp no_acpi_power_off |
144 | jmp no_acpi_power_off |
145 | do_acpi_power_off: |
145 | do_acpi_power_off: |
146 | mov edx, [ebx+48] |
146 | mov edx, [ebx+48] |
147 | test edx, edx |
147 | test edx, edx |
148 | jz .nosmi |
148 | jz .nosmi |
149 | mov al, [ebx+52] |
149 | mov al, [ebx+52] |
150 | out dx, al |
150 | out dx, al |
151 | mov edx, [ebx+64] |
151 | mov edx, [ebx+64] |
152 | @@: |
152 | @@: |
153 | in ax, dx |
153 | in ax, dx |
154 | test al, 1 |
154 | test al, 1 |
155 | jz @b |
155 | jz @b |
156 | .nosmi: |
156 | .nosmi: |
157 | and cx, 0x0707 |
157 | and cx, 0x0707 |
158 | shl cx, 2 |
158 | shl cx, 2 |
159 | or cx, 0x2020 |
159 | or cx, 0x2020 |
160 | mov edx, [ebx+64] |
160 | mov edx, [ebx+64] |
161 | in ax, dx |
161 | in ax, dx |
162 | and ax, 203h |
162 | and ax, 203h |
163 | or ah, cl |
163 | or ah, cl |
164 | out dx, ax |
164 | out dx, ax |
165 | mov edx, [ebx+68] |
165 | mov edx, [ebx+68] |
166 | test edx, edx |
166 | test edx, edx |
167 | jz @f |
167 | jz @f |
168 | in ax, dx |
168 | in ax, dx |
169 | and ax, 203h |
169 | and ax, 203h |
170 | or ah, ch |
170 | or ah, ch |
171 | out dx, ax |
171 | out dx, ax |
172 | @@: |
172 | @@: |
173 | jmp $ |
173 | jmp $ |
174 | 174 | ||
175 | no_acpi_power_off: |
175 | no_acpi_power_off: |
176 | jmp 0x50000 |
176 | jmp 0x50000 |
177 | 177 | ||
178 | align 4 |
178 | align 4 |
179 | restart_code_start: |
179 | restart_code_start: |
180 | org 0x50000 |
180 | org 0x50000 |
181 | 181 | ||
182 | cmp byte [BOOT_SHUTDOWN_TYPE], SYSTEM_RESTART |
182 | cmp byte [BOOT_LO.shutdown_type], SYSTEM_RESTART |
183 | jne @F |
183 | jne @F |
184 | 184 | ||
185 | mov esi, _CLEAN_ZONE-OS_BASE |
185 | mov esi, _CLEAN_ZONE-OS_BASE |
186 | mov edi, 0x10000 |
186 | mov edi, 0x10000 |
187 | mov ecx, 0x31000/4 |
187 | mov ecx, 0x31000/4 |
188 | cld |
188 | cld |
189 | rep movsd |
189 | rep movsd |
190 | @@: |
190 | @@: |
191 | 191 | ||
192 | xor ebx, ebx |
192 | xor ebx, ebx |
193 | xor edx, edx |
193 | xor edx, edx |
194 | xor ecx, ecx |
194 | xor ecx, ecx |
195 | xor esi, esi |
195 | xor esi, esi |
196 | xor edi, edi |
196 | xor edi, edi |
197 | xor ebp, ebp |
197 | xor ebp, ebp |
198 | lidt [.idt] |
198 | lidt [.idt] |
199 | lgdt [.gdt] |
199 | lgdt [.gdt] |
200 | jmp 8:@f |
200 | jmp 8:@f |
201 | align 8 |
201 | align 8 |
202 | .gdt: |
202 | .gdt: |
203 | ; selector 0 - not used |
203 | ; selector 0 - not used |
204 | dw 23 |
204 | dw 23 |
205 | dd .gdt |
205 | dd .gdt |
206 | dw 0 |
206 | dw 0 |
207 | ; selector 8 - code from 5000:0000 to 1000:FFFF |
207 | ; selector 8 - code from 5000:0000 to 1000:FFFF |
208 | dw 0FFFFh |
208 | dw 0FFFFh |
209 | dw 0 |
209 | dw 0 |
210 | db 5 |
210 | db 5 |
211 | db 10011011b |
211 | db 10011011b |
212 | db 00000000b |
212 | db 00000000b |
213 | db 0 |
213 | db 0 |
214 | ; selector 10h - data from 1000:0000 to 1000:FFFF |
214 | ; selector 10h - data from 1000:0000 to 1000:FFFF |
215 | dw 0FFFFh |
215 | dw 0FFFFh |
216 | dw 0 |
216 | dw 0 |
217 | db 1 |
217 | db 1 |
218 | db 10010011b |
218 | db 10010011b |
219 | db 00000000b |
219 | db 00000000b |
220 | db 0 |
220 | db 0 |
221 | .idt: |
221 | .idt: |
222 | dw 256*4 |
222 | dw 256*4 |
223 | dd 0 |
223 | dd 0 |
224 | org $ - 0x50000 |
224 | org $ - 0x50000 |
225 | use16 |
225 | use16 |
226 | @@: |
226 | @@: |
227 | mov ax, 10h |
227 | mov ax, 10h |
228 | mov ds, ax |
228 | mov ds, ax |
229 | mov es, ax |
229 | mov es, ax |
230 | mov fs, ax |
230 | mov fs, ax |
231 | mov gs, ax |
231 | mov gs, ax |
232 | mov ss, ax |
232 | mov ss, ax |
233 | 233 | ||
234 | mov eax, cr0 |
234 | mov eax, cr0 |
235 | and eax, not 80000001h |
235 | and eax, not 80000001h |
236 | mov cr0, eax |
236 | mov cr0, eax |
237 | jmp 0x5000:.real_mode |
237 | jmp 0x5000:.real_mode |
238 | 238 | ||
239 | align 4 |
239 | align 4 |
240 | .real_mode: |
240 | .real_mode: |
241 | 241 | ||
242 | ; setup stack |
242 | ; setup stack |
243 | 243 | ||
244 | mov ax, (TMP_STACK_TOP and 0xF0000) shr 4 |
244 | mov ax, (TMP_STACK_TOP and 0xF0000) shr 4 |
245 | mov ss, ax |
245 | mov ss, ax |
246 | mov esp, TMP_STACK_TOP and 0xFFFF |
246 | mov esp, TMP_STACK_TOP and 0xFFFF |
247 | 247 | ||
248 | ;remap IRQs |
248 | ;remap IRQs |
249 | mov al, 0x11 |
249 | mov al, 0x11 |
250 | out 0x20, al |
250 | out 0x20, al |
251 | out 0xA0, al |
251 | out 0xA0, al |
252 | 252 | ||
253 | mov al, 0x08 |
253 | mov al, 0x08 |
254 | out 0x21, al |
254 | out 0x21, al |
255 | mov al, 0x70 |
255 | mov al, 0x70 |
256 | out 0xA1, al |
256 | out 0xA1, al |
257 | 257 | ||
258 | mov al, 0x04 |
258 | mov al, 0x04 |
259 | out 0x21, al |
259 | out 0x21, al |
260 | mov al, 0x02 |
260 | mov al, 0x02 |
261 | out 0xA1, al |
261 | out 0xA1, al |
262 | 262 | ||
263 | mov al, 0x01 |
263 | mov al, 0x01 |
264 | out 0x21, al |
264 | out 0x21, al |
265 | out 0xA1, al |
265 | out 0xA1, al |
266 | 266 | ||
267 | mov al, 0xB8 |
267 | mov al, 0xB8 |
268 | out 0x21, al |
268 | out 0x21, al |
269 | mov al, 0xBD |
269 | mov al, 0xBD |
270 | out 0xA1, al |
270 | out 0xA1, al |
271 | 271 | ||
272 | mov al, 00110100b |
272 | mov al, 00110100b |
273 | out 43h, al |
273 | out 43h, al |
274 | mov al, 0xFF |
274 | mov al, 0xFF |
275 | out 40h, al |
275 | out 40h, al |
276 | out 40h, al |
276 | out 40h, al |
277 | 277 | ||
278 | xor ax, ax |
278 | xor ax, ax |
279 | mov ds, ax |
279 | mov ds, ax |
280 | mov al, [BOOT_SHUTDOWN_TYPE] |
280 | mov al, [BOOT_LO.shutdown_type] |
281 | cmp al, SYSTEM_RESTART |
281 | cmp al, SYSTEM_RESTART |
282 | je .restart |
282 | je .restart |
283 | 283 | ||
284 | cmp al, SYSTEM_SHUTDOWN |
284 | cmp al, SYSTEM_SHUTDOWN |
285 | je .APM_PowerOff |
285 | je .APM_PowerOff |
286 | 286 | ||
287 | mov word[0x0472], 0x1234 |
287 | mov word[0x0472], 0x1234 |
288 | jmp 0xF000:0xFFF0 |
288 | jmp 0xF000:0xFFF0 |
289 | 289 | ||
290 | .APM_PowerOff: |
290 | .APM_PowerOff: |
291 | mov ax, 5304h |
291 | mov ax, 5304h |
292 | xor bx, bx |
292 | xor bx, bx |
293 | int 15h |
293 | int 15h |
294 | ;!!!!!!!!!!!!!!!!!!!!!!!! |
294 | ;!!!!!!!!!!!!!!!!!!!!!!!! |
295 | mov ax, 0x5300 |
295 | mov ax, 0x5300 |
296 | xor bx, bx |
296 | xor bx, bx |
297 | int 0x15 |
297 | int 0x15 |
298 | push ax |
298 | push ax |
299 | 299 | ||
300 | mov ax, 0x5301 |
300 | mov ax, 0x5301 |
301 | xor bx, bx |
301 | xor bx, bx |
302 | int 0x15 |
302 | int 0x15 |
303 | 303 | ||
304 | mov ax, 0x5308 |
304 | mov ax, 0x5308 |
305 | mov bx, 1 |
305 | mov bx, 1 |
306 | mov cx, bx |
306 | mov cx, bx |
307 | int 0x15 |
307 | int 0x15 |
308 | 308 | ||
309 | mov ax, 0x530E |
309 | mov ax, 0x530E |
310 | xor bx, bx |
310 | xor bx, bx |
311 | pop cx |
311 | pop cx |
312 | int 0x15 |
312 | int 0x15 |
313 | 313 | ||
314 | mov ax, 0x530D |
314 | mov ax, 0x530D |
315 | mov bx, 1 |
315 | mov bx, 1 |
316 | mov cx, bx |
316 | mov cx, bx |
317 | int 0x15 |
317 | int 0x15 |
318 | 318 | ||
319 | mov ax, 0x530F |
319 | mov ax, 0x530F |
320 | mov bx, 1 |
320 | mov bx, 1 |
321 | mov cx, bx |
321 | mov cx, bx |
322 | int 0x15 |
322 | int 0x15 |
323 | 323 | ||
324 | mov ax, 0x5307 |
324 | mov ax, 0x5307 |
325 | mov bx, 1 |
325 | mov bx, 1 |
326 | mov cx, 3 |
326 | mov cx, 3 |
327 | int 0x15 |
327 | int 0x15 |
328 | ;!!!!!!!!!!!!!!!!!!!!!!!! |
328 | ;!!!!!!!!!!!!!!!!!!!!!!!! |
329 | jmp $ |
329 | jmp $ |
330 | 330 | ||
331 | .restart: |
331 | .restart: |
332 | 332 | ||
333 | ; (hint by Black_mirror) |
333 | ; (hint by Black_mirror) |
334 | ; We must read data from keyboard port, |
334 | ; We must read data from keyboard port, |
335 | ; because there may be situation when previous keyboard interrupt is lost |
335 | ; because there may be situation when previous keyboard interrupt is lost |
336 | ; (due to return to real mode and IRQ reprogramming) |
336 | ; (due to return to real mode and IRQ reprogramming) |
337 | ; and next interrupt will not be generated (as keyboard waits for handling) |
337 | ; and next interrupt will not be generated (as keyboard waits for handling) |
338 | 338 | ||
339 | mov cx, 16 |
339 | mov cx, 16 |
340 | @@: |
340 | @@: |
341 | in al, 0x64 |
341 | in al, 0x64 |
342 | test al, 1 |
342 | test al, 1 |
343 | jz @F |
343 | jz @F |
344 | in al, 0x60 |
344 | in al, 0x60 |
345 | loop @B |
345 | loop @B |
346 | @@: |
346 | @@: |
347 | 347 | ||
348 | ; bootloader interface |
348 | ; bootloader interface |
349 | push 0x1000 |
349 | push 0x1000 |
350 | pop ds |
350 | pop ds |
351 | push 0 |
351 | push 0 |
352 | pop es |
352 | pop es |
353 | mov si, [es:BOOT_KERNEL_RESTART] |
353 | mov si, [es:BOOT_LO.kernel_restart] |
354 | mov ax, 'KL' |
354 | mov ax, 'KL' |
355 | jmp 0x1000:0000 |
355 | jmp 0x1000:0000 |
356 | 356 | ||
357 | align 4 |
357 | align 4 |
358 | org restart_code_start + $ |
358 | org restart_code_start + $ |
359 | restart_code_end: |
359 | restart_code_end: |
360 | 360 | ||
361 | org $+OS_BASE |
361 | org $+OS_BASE |
362 | use32 |
362 | use32 |