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